3

これはJavaにとって非常に基本的な質問かもしれませんが、私はそれを思い出せず、オンラインで検索する方法がわかりません。

button.setOnClickListener(new OnClickListener()
{
  @Override
   public void onClick(View v)
   {
     Thread.sleep(100);
   }
}

私はのようなコンストラクターを使用してオブジェクトを初期化することに慣れていますnew OnClickListener(arg1, arg2, ...)。私自身の経験では、オブジェクトを作成するときにメソッドをオーバーライドしたことはありません。私はクラスを拡張するときにのみそれを行いました。Javaでこの種のインスタンス化と呼ばれる用語がある場合、それは何ですか?他にどのような場合に使用する必要がありますか?

4

4 に答える 4

6

それは匿名のクラスです。これはOnClickListenerインターフェースの実装ですが、その実装には名前がありません。書くのは簡潔で、実装は呼び出し元のコンテキストで表示されます(読みやすさのために役立つことがよくあります)が、実装はインプレースであるため、他の場所で使用することはできません。

また、これは内部クラスであるため、周囲のクラスへの参照があることにも注意してください。

詳細については、こちらをご覧ください。

再。周囲のクラスへの参照。内部クラスには、その外部クラスへの暗黙の参照があります(たとえば、XStreamを使用して内部クラスをシリアル化しようとすると、これを確認できます。外部クラスも一緒にプルされます)。外側のクラスに変数がある場合は、内側のクラスでそれを参照できます(final変数である場合は注意してください)

于 2012-12-03T11:53:41.027 に答える
3

それらは匿名クラスと呼ばれます。

技術的には、これらはインスタンス化されるクラスのサブクラスであり、オーバーライドされたメソッドの実装を提供します。

これらは、トップレベルのクラスを明確に宣言せずに実装を提供する場合に役立ちます。

これらは、クロージャに対するJavaの答えです。

于 2012-12-03T11:53:23.427 に答える
2
new OnClickListener()
{
  @Override
  public void onClick(View v)
  {
    Thread.sleep(100);
  }
}

構文とセマンティクスの両方の観点から、この構成はインスタンス化クラス宣言を組み合わせたものです。同じように、呼び出すコンストラクターを指定しOnClickListener(この目的のために、インターフェースにはデフォルトのコンストラクターがあると想定されます)、宣言する新しいサブクラスに属するクラス本体を提供します。サブクラスに名前を付けていないため、この構造は「匿名クラス」と呼ばれます。匿名クラスのインスタンス化は宣言と密接に関連しており、宣言されている場所を除いて、コード内の他のポイントからこのクラスをインスタンス化することはできません。

Javaには、実際に使用されることはほとんどない、ほぼ同じ構造があります。ローカルクラスです。これは通常のクラス宣言と同じように見えますが、上記の匿名クラスと同じように、メソッド内で発生します。この場合、クラスには名前が付けられ、いくつかの場所で参照およびインスタンス化できますが、それらはすべて、宣言されているメソッド内にあります。

どちらの場合も、他のクラスでは使用できない特別な機能を利用できます。これは、メソッドで宣言されたローカル変数を使用する機能です。メソッドが完了するとローカル変数が消えるので、これは最初は奇妙ですが、ローカルクラスのインスタンスへの参照は存続します。これが、これらのクラスが「クロージャ」と呼ばれる理由です。これらのクラスは、ローカル環境を「閉じる」と言われています。それらは一種の変数宣言を「持ち上げ」、それらをインスタンス変数として保持します。

于 2012-12-03T11:58:11.833 に答える
1

これがどのように使用できるかの例を少し挙げるだけです...

public class TestClass {
    public static void main(String args[]) {
        OutOfTheMain ootm = new OutOfTheMain();
    }
}

public interface SuperInner {
    String words = "hello";
    String getWords();
}

public class OutOfTheMain {
    OutOfTheMain() {
        testInnerStuff(new SuperInner() {
            @Override
            public String getWords() {
                return words + " world";
            }
        });
    }

    private void testInnerStuff(SuperInner sinner) {
        System.out.println(sinner.getWords());
    }
}

実行すると、これは印刷されます...

hello world

メソッドをオーバーライドして機能を追加し、後で実行時にこのクラスを使用できます。

于 2012-12-03T12:20:14.693 に答える