2012-04-01 24 views
4

匿名の外部クラスにアクセスする方法はありますか?通常のクラスはClassNameによってアクセスできます。匿名クラスは明らかに名前を持たないため、これは機能しません。私はまた、拡張クラス/インタフェース(Runnable.thisのような)を使ってみましたが、このように動作するようには見えません。変数に格納せずに匿名の外部クラスにアクセスしますか?

これは最高のコーディングスタイルではないと確信していますが、変数の外側にこれを保存しなくても可能ならば、私はちょうど興味があります。

例は、outer.thisに注意:

public class A 
{ 
    public static void main(String[] args) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       new Thread(new Runnable() { 
        @Override 
        public void run() { 
         synchronized (outher.this) { 
          outher.this.notify(); 
         } 
        } 
       }).start(); 
       try { 
        synchronized (this) { 
         wait(); 
        } 
       } catch (final InterruptedException ex) {} 
      } 
     }).start(); 
    } 
} 

答えて

2

ありませんが、その中から除き、どこからでも匿名クラスにアクセスする方法はありません(すなわち、そうでない場合はthis参照することによってより)。または、明示的に宣言された変数。

final Runnable r1 = new Runnable() {...}; 
Runnable r2 = new Runnable() { 
    public void run() { 
     synchronized(r1) {...} 
    } 
}; 
+0

匿名クラスを使用してsynchronized(this.getClass()。getEnclosingClass())と動作すると思いますか? –

+0

@エリックR.私はそれがDiddiZが投稿したものとは異なる何かをすると思います(あなたが提案するのはDiddiZが本当に望んでいるものかもしれません)。 'main'メソッドが多くの異なるスレッドで同時に実行されていたとします。 DiddiZのコードでは、それらはすべて異なるオブジェクトに同期しているため、競合はありません。あなたのコードでは、それらはすべて同じオブジェクトに同期しているので、いくつかの競合があります。しかし、私はあなたのコードがDiddiZが本当に望んでいるものだと思っています。 – emory

+0

これは、インスタンスではなくクラスによって同期されます。同期の変更(this.getClass()。getEnclosingClass())とsynchronized(this.getClass())の同期が(synchronized(this)の代わりに)監視されている場合、これは機能します。しかし、同じRunnableインスタンス上で複数のスレッドを実行すると、静的に同期されるようになります。つまり、すべてのインスタンスにわたって同期されます。 –

1

この中間に戻す方法を追加できます。this。それは範囲にあるが隠されていないだろう(それは正しい言葉なのだろうか?影を付けた?私は忘れる)。

public static void main(String[] args) { 
    new Thread(new Runnable() { 
     Runnable middleThis() { return this; } // <-- this 
     @Override 
     public void run() { 
      new Thread(new Runnable() { 
       @Override 
       public void run() { 
        synchronized (middleThis()) { 
         middleThis().notify(); 

匿名の内部クラスには名前はありませんが、依然として型です。したがって、メンバーの追加は即時式(new X() { Y z; }.z)と内部に表示されます。 middleThis().middleThis()はできません。

+0

これは、「変数に格納せずに」制限を回避する巧妙な方法です。 – emory

関連する問題