2011-01-14 7 views
0

私はJavaに関するもう一つの「哲学的な」質問を受けました。次のシナリオについてです。"Listener"クラスの実装の違いは何ですか?

リスナーとして使用するインターフェイスLと、2番目のクラスのNotifierのインターフェイスを定義するTクラスがあります。

これで、次のコードではABのクラスになりました。そのクラスは、クラスTの新しいオブジェクトを作成し、Lを使用します。これは後者が最初のオブジェクトと通信するために使用します。 ALの実装、クラスLLを定義し、作成するために、それの新しいオブジェクトを使用し

  • クラス:

    だから私は、リスナーオブジェクトがTに渡さすることができますどのようにそれの4つの異なるバージョンを発表しますTクラス。
    1. A1

    2. A2
  • クラスBL(感謝ティム・ベンダーの匿名クラスを使用してオブジェクトを作成するインライン方法を使用してその場で新しいオブジェクトを作成し、オブジェクトを事前に割り当て修正のために)

    1. B1オブジェクトを事前に割り当てる
    2. B2は、私の質問があるスポット

に新しいオブジェクトを作成し、これらのバージョンのいずれかが何らかの形で、より効率的でしょうか?何らかの理由で安全なものではありませんか?議論し、他のバージョンを示唆し、説明してください!

クラスT

class T extends TT{ 
    public interface L{ 
     public void do(int i); 
    } 

    private L Lo; 

    T(L i){ 
     Lo = i; 
    } 

    public void start(){ 
     // do stuff 
     L.do(0); 
    } 
} 

クラス

class A1{ 
    private class LL implements L{ 
     @Override 
     public void do(int i){ 
      // do stuff 
     } 
    } 

    private LL l = new LL(); 

    public void function(){ 
     T t = new T(l) 
    } 
} 

class A2{ 
    private class LL implements L{ 
     @Override 
     public void do(int i){ 
      // do stuff 
     } 
    } 

    public void function(){ 
     T t = new T(new LL()) 
    } 
} 

クラスB

class B1{ 
    private L l = new L(){ 
     @Override 
     public void do(int i){ 
      // do stuff 
     } 
     }; 

    public void function(){ 
     T t = new T(l); 
    } 
} 

class B2{ 
    public void function(){ 
     T t = new T(new L(){ 
      @Override 
      public void do(int i){ 
       // do stuff 
      } 
     }); 
    } 
} 
+2

"クラスBは、インターフェイスLを明示的に実装せずにオブジェクトを作成するインラインの方法を使用します"という記述は間違っています。インタフェースLは明示的に実装されています。説明しようとしていることは、一般的に匿名クラスと呼ばれます。 –

+0

@Tim Bender、訂正ありがとうございました。だから、基本的に 'A'と' B'はバイナリに関して全く違うわけではなく、プログラマの選択になります。 – alkar

答えて

2

A及びB(匿名クラスを使用して)との差は、ランタイム差はありません。このコードをコンパイルすると、B1 $ 1のような識別子を使って匿名クラスが作成されます。コンパイルしたbinディレクトリでそのクラスファイルを調べることさえできます。

1と2の唯一の違いは、メンバー変数を作成することによって、包含するクラスのインスタンスをインスタンス化するために必要なサイズが膨らんでいることです。メンバ変数は、必要に応じて(再利用目的で)作成する必要があります。

しかし、最も重要なことですが、開発時の主な懸念事項は、常に明確かつ正確でなければなりません。パフォーマンスの問題が後で発生する場合は、問題のある領域を特定する分析ツールを使用して機能するアプリケーションにアプローチする方がはるかに優れています。または、静的分析ツールを使用して、小さくても簡単な利益(低吊り果物)を特定することもできます。

+0

合意。コンパイラとホットスポットエンジンがどのような最適化を行うのかは決して分かりません(コンパイラの場合を除きます)。 –

+0

'finish()'関数がアプリケーションの存続期間中に数回(あるいはたぶんかなり)呼び出されるとはどういうことでしょうか?それでは、メンバ変数のメソッドを使うのが良いでしょうか?毎回新しいオブジェクトを作成する必要がなければ、実際にパフォーマンスに影響を与えますか? – alkar

2

ソフトウェアの効率性に大きな違いはありません。それはプログラマーの効率とより大きな文脈に本当に沸騰します。一度しか使用されないことが分かっている場合は、より簡潔なので、一般的に好ましい方法はB2です。 A1はより冗長ですが、再利用可能です。また、適切な変数名を選択することによって、冗長性はすべて自己完結型のコードにすることができます。

個人的な傾向は、外部クラスがインターフェイスを実装し、thisがコンストラクタに渡される3番目のオプションです。

関連する問題