2

匿名クラスとローカルクラスを使用してクロージャを実装する際の違いについて、いくつか検索しました。私は2つの違いをすべて理解しようとしているので、どの方法がどの状況で優れているかがわかります。

私が間違っている場合は私を訂正してください:

  • 匿名クラスには、新しいインスタンスが作成されるたびに作成されるクラスインスタンスとオブジェクトインスタンスがあります。
  • ローカルクラスには、新しいインスタンスが作成されるたびに作成されるオブジェクトインスタンスのみがあります。

したがって、ローカルクラスよりも匿名クラスを使用する必要がある時間や場所はありますか?

編集:2つの間に実際の違いはないようです。スタイルと、クラスを再利用するかどうかによって異なります。

ここで私が何を意味するのかを明確にするために、私が話していることの例を示します。

public class ClosureExample {
interface Function {
    void func(int value);
}

public static void main(final String[] args) {
    final Function local1 = localClassClosure("Local1");
    final Function local2 = localClassClosure("Local2");

    final Function anonymous1 = anonymousClassClosure("Annonymous1");
    final Function anonymous2 = anonymousClassClosure("Annonymous2");

    for (int i = 0; i < 3; i++) {
        local1.func(i);
        local2.func(i);
        anonymous1.func(i);
        anonymous2.func(i);
    }
}

private static Function localClassClosure(final String text) {
    // Local class name is irrelevant in this example
    class _ implements Function {
        @Override public void func(final int value) {
            System.out.println(text + ":" + value);
        }
    }
    return new _();
}

private static Function anonymousClassClosure(final String text) {
    return new Function() {
        @Override public void func(final int value) {
            System.out.println(text + ":" + value);
        }
    };
}
}

うまくいけば、誰かがこの微妙な違いと、どのような状況でどの方法を使用すべきかを詳細に説明できるでしょう。

4

4 に答える 4

2

これは私の興味をそそり、逆コンパイルされたクラスを調べるためにJD-GUIを起動しました。コンパイル後、実際には2つの匿名内部クラスの間にまったく違いはありません。

localClass:

class ClosureExample$1t implements ClosureExample.Function{
  ClosureExample$1t(String paramString){
  }

  public void func(int value){
    System.out.println(this.val$text + ":" + value);
  }
}

analogClass:

class ClosureExample$1 implements ClosureExample.Function{
  ClosureExample$1(String paramString){
  }

  public void func(int value){
    System.out.println(this.val$text + ":" + value);
  }
}

どちらのメソッドも匿名の内部クラスを実装する有効な方法であり、まったく同じことを行うようです。

編集:私は_クラスの名前をtに変更しました

于 2012-09-23T00:34:38.193 に答える
0

オブジェクトインスタンスのようなものはなく、クラスインスタンスだけだと確信しています。つまり、オブジェクトはローカルタイプと匿名タイプの両方に対して作成されます。ただし、違いは、匿名クラスを再利用できないことです(メソッドで使用した方法を除いて、機能しますが、実際には保守できません)。あなたがしていることが1回限りのことであるとき。たとえば、イベントリスナーを使用します。

ただし、匿名タイプよりも名前付きタイプの方が好きです。

これは便利だと思うかもしれません

編集:ここで 私の質問が役に立ちます。

于 2012-09-23T00:21:08.803 に答える
0
  1. ローカルクラスオブジェクトは初期化時に高速です(クラスは起動時にすでにメモリにあるため)
  2. 匿名クラスオブジェクトのメモリ消費量が少ない(遅延評価のため)

注意:Javaは実際の関数型言語ではないためです。匿名クラスは事前に評価され、クラスファイルに保存されます。ですから、実際には大きな違いはありません。

スキームのような関数型言語で:

(define inc (lambda (a) (lambda () (+ 1 a))))
(display ((inc 5))) 

関数(lambda()(+ 1 a))は、((inc 5))のような匿名呼び出しごとに実際に再作成されます。これが匿名クラスの背後にある概念です。

とは対照的に:

(define inc (lambda (a) (+ 1 a)))
(display (inc 5)) 

ここで、(lambda(a)(+ 1 a))はコンパイル時にメモリに格納され、(inc 5)の呼び出しはそれを参照するだけです。これがローカルクラスの背後にある概念です。

于 2012-09-23T00:30:48.307 に答える
0

これについてのメモ:

したがって、ローカルクラスよりも匿名クラスを使用する必要がある時間や場所はありますか?

コンポーネント内でイベントリスナー[たとえば]をすばやく設定する必要がある場合はKeyListener、次のように実行できます。

addKeyListener(new KeyListener(){

    public void keyPressed(KeyEvent ke){ ... }

    // further implementation here

});

再利用はできませんが。

于 2012-09-23T00:39:50.713 に答える