反復子の実装を列挙子のインタフェイスで扱う #4
このenumeration(Iterator)はもっと簡潔に書くことができた。
...snip public static <E> Enumeration<E> enumeration(final Iterator<E> iterator) { return new Enumeration<E>() { public boolean hasMoreElements() { return iterator.hasNext(); } public E nextElement() { return iterator.next(); } }; } ...snip
メソッドの戻り値用のEnumerationを実装した匿名クラスにわざわざIteratorを保持する記述をする必要はない。
この匿名クラスをコンパイル後、javapコマンドで見ると、
final java.util.Iterator val$iterator;
というfinalフィールドが勝手に作成され、
Signature: (Ljava/util/Iterator;)V
なるシグニチャを持つコンストラクタが自動で作られている。
つまりこのコンストラクタはIteratorを引数に取り、この中で、
0: aload_0 1: aload_1 2: putfield #1 // Field val$iterator:Ljava/util/Iterator; 5: aload_0 6: invokespecial #2 // Method java/lang/Object."<init>":()V 9: return
のようにval$iteratorに引数を代入している。
Iteratorを使用するメソッド側、例えばhasMoreElements()では、
0: aload_0 1: getfield #1 // Field val$iterator:Ljava/util/Iterator; 4: invokeinterface #3, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z 9: ireturn
のようにval$iteratorを参照している。
つまり、#3における
private Iterator<E> iter = iterator;
のような記述をしなくても自動でコンパイラが作成してくれ、
また、enumeration(Iterator)が匿名クラスをnewする時には、
iteratorを引数としてシグニチャ(Ljava/util/Iterator;)Vのコンストラクタを呼び出すようにしてくれるので、
ソースには匿名クラスのメソッド内で直接iteratorを利用するように記述しておけば済む。