この質問では、TofuBeer は一般化された .xml の作成に問題がありましたIterableEnumeration
。
答えは、問題をほぼ解決したこのリンクhttp://www.javaspecialists.eu/archive/Issue107.htmlを指している jcrossley3 から来ました。
まだ一つ腑に落ちないことがあります。エリクソンが効果的に指摘したように、本当の問題は次のとおりです。
パラメーター化された型を構築するときにワイルドカードを指定することはできません
ただし、宣言でワイルドカードを削除しても機能しませんでした。
final IterableEnumeration<ZipEntry> iteratable
= new IterableEnumeration<ZipEntry>(zipFile.entries());
次のエラーが発生します。
Main.java:19: cannot find symbol
symbol : constructor IterableEnumeration(java.util.Enumeration<capture#469 of ? extends java.util.zip.ZipEntry>)
location: class IterableEnumeration<java.util.zip.ZipEntry>
final IterableEnumeration<ZipEntry> iteratable = new IterableEnumeration<ZipEntry>( zipFile.entries());
^
1 error
しかし、JavaSpecialist のサンプルは機能します。
IterableEnumeration<String> ie =
new IterableEnumeration<String>(sv.elements());
私が見つけることができる唯一の違いは、JavaSpecialists ブログでは、署名が次Enumeration
の から来ていることです。Vector
public Enumeration<E> elements()
失敗したものはZipFile
、署名が次のとおりです。
public Enumeration<? extends ZipEntry> entries()
最後に、これはすべて for-each コンストラクトとリンクで提案されている static make メソッドによって吸収されます
for(final ZipEntry entry : IterableEnumeration.make( zipFile.entries() )) {
if(!(entry.isDirectory())) {
names.add(entry.getName());
}
}
しかし!!そのニュースレターのポイントは、この問題を解決することではなく、ジェネリック型を指定する必要性を回避することでした。構文が見苦しいからです!!
だから..私の質問は:
何が起こっている?
IterableEnumeration
パラメータEnumeration
の型が である場合、なぜインスタンスを作成しないの<? extends SomeClass>
ですか そして、make for-each 構造が問題を飲み込むのはなぜですか?!!!
なぜこれが機能するのですか:
for(final ZipEntry entry : IterableEnumeration.make( zipFile.entries() )) {
しかし、これはうまくいきませんか?
final IterableEnumeration<ZipEntry> iteratable
= IterableEnumeration.make( zipFile.entries() );
以下は、TofuBeer の元のコードの (わずかに) 変更されたバージョンです。
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.Vector;
public class Main {
private ZipFile zipFile;
public Set<String> entries() {
final Vector<ZipEntry> vector = new Vector<ZipEntry>();
// why this works.
//final IterableEnumeration<ZipEntry> iteratable = new IterableEnumeration<ZipEntry>( vector.elements() );
// but this do not.
//final IterableEnumeration<ZipEntry> iteratable = new IterableEnumeration<ZipEntry>( zipFile.entries() );
// nor this
final IterableEnumeration<ZipEntry> iteratable = IterableEnumeration.make( zipFile.entries() );
// And what's with the for-each that doesn't care about the type?
final Set<String> names = new HashSet<String>();
for(final ZipEntry entry : IterableEnumeration.make( zipFile.entries() )) {
if(!(entry.isDirectory())) {
names.add(entry.getName());
}
}
return (names);
}
}
class IterableEnumeration<T> implements Iterable<T> {
private final Enumeration<T> enumeration;
public IterableEnumeration(final Enumeration<T> e) {
enumeration = e;
}
public Iterator<T> iterator() {
return new Iterator<T>() {
public boolean hasNext() {
return (enumeration.hasMoreElements());
}
public T next() {
return (enumeration.nextElement());
}
public void remove() {
throw new UnsupportedOperationException("Cannot remove via an Enumeration");
}
};
}
// As suggested by http://www.javaspecialists.eu/archive/Issue107.html
// but doesn't help with: final IterableEnumeration<ZipEntry> iteratable = IterableEnumeration.make( zipFile.entries() );
public static <T> Iterable<T> make(Enumeration<T> en) {
return new IterableEnumeration<T>(en);
}
}
理解したい!!