3

私はよくわからない奇妙な現象に直面しています。他のいくつかのクラスによって拡張された抽象クラスがあります。抽象クラスは特別なコレクションの一種であり、それに適合するネストされた抽象反復子クラスがあります。抽象コレクション クラスを拡張するすべてのクラスには、元の抽象反復子を拡張するネスト反復子クラスもあります。

抽象クラスは次のようなものです。

public abstract class AbstractMultiCollection<T> {

    public AbstractMultiCollection() {
    ...
    }

    MultiIterator<T> iterator();

    public abstract class AbstractMultiIterator {
        public AbstractMultiIterator() {
        ...
        }

拡張クラスは次のようなものです。

public class MajorityMultiCollection<T> extends AbstractMultiCollection<T> {
...
    public MultiIterator<T> iterator() {
        return new MajorityIterator();
    }
    ...     

    public class MajorityIterator extends AbstractMultiIterator {

        public MajorityIterator() {
        super();
        ...
        }

        public T next() {
        ...
        }

簡単に言えば、コレクションは抽象コレクションを拡張し、そのネストされた反復子はネストされた抽象反復子を拡張します。

理解できない問題が 2 つあります。説明をいただければ幸いです。

  1. コードをデバッグすると、「return new MajorityIterator();」行は、Eclipseデバッガーで「Source Not Found」エラーと「ClassNotFound」例外、および理解できない「ClassLoaderExt」例外の束を発生させます。
  2. すべての「MajorityIterator」には、彼が属するコレクションを含む 2 つの「This$0」フィールドがあることに気付きました。1 つは最初は null ですが、「super();」を呼び出すとコレクションを受け取ります。ビルダー。

この理由を見つけることができませんでした。誰か明確にできますか? 前もって感謝します!

4

2 に答える 2

4

実際には、2 つのthis参照を持つことは理にかなっています。ほとんどの人が気づいていないことの 1 つは、Java コンパイラが非静的なネストされたクラスを実装する方法です

  • 外部クラスの型を持つ新しいフィールドを暗黙的に追加し、それを呼び出しましょうouter$object

  • 外部クラス オブジェクトの新しい引数をすべてのコンストラクターに暗黙的に追加して、そのフィールドに入力します。ちなみに、これは、内部クラスのデフォルトのコンストラクターが実際にパラメーターを持っていることを意味し、リフレクションを介してそれを使用することは非常に複雑になります。

  • 内部クラスが宣言されている場合など、アクセシビリティの問題を回避するために、より広い可視性を持つコンストラクターとメソッドを暗黙的に作成しますprivate

フィールドは外部クラスと同じ型である必要があるため、ネストされたクラスが同じ外部クラス内でネストされていないouter$objectクラスから継承されるたびに、フィールドが追加されます。

個人的には、私は非静的で非匿名の内部クラスを避ける傾向があります。これは、コンパイラーに物事を混乱させるのではなく、すべてを明示的に表面に保持するためです...

于 2012-12-31T09:16:33.813 に答える
3

MajorityIteratorオブジェクトには実際に 2 つのフィールドthis$0があります。

  • MajorityIteratorの外側のインスタンスへの参照用の1 つ ( で暗黙的に宣言)MajorityMultiCollection
  • AbstractMultiIteratorの外側のインスタンスへの参照用の1 つ ( で暗黙的に宣言) AbstractMultiCollectionsuper()これは、コンストラクターで設定されるため、呼び出しまで null になります。

これらの静的なネストされたクラスを作成し、代わりに外側のインスタンスへの参照を明示的に渡す方が明確であることに気付くかもしれません-参照が1つだけ必要であると思われ、その方が簡単に推論できます。

于 2012-12-31T09:13:52.093 に答える