2017-12-12 11 views
0

Javaでは、メソッドで定義されたクラスに何らかの手段(反射など)でアクセスできますか?そしてどうやって?例えばJavaのメソッドで定義されたアクセスクラス

、私は以下の例でInnerClassのインスタンスを作成したい:回答を

class Example { 
    public void outerMethod() { 
     class InnerClass { 
      double d = 0; 
     } 
    } 

    public void testMethod() { 
     outerMethod::InnerClass instance = new outerMethod::InnerClass(); 
    } 
} 

感謝を。

+3

を呼び出すだけで作成したオブジェクトを印刷します。他の場所からアクセスする場合は、より高いスコープで定義します。 –

+0

私は現在、Javaコードで動作するツールを開発中です。だから私はツールが自動的に内部クラスの場所を変更するかどうかは、コードのcorectnessを破ることができるかどうかを知る必要があります。 –

+0

そして、開発者として私はそれがどのようにできるかを理解する必要があります。 user882813に感謝します。 –

答えて

0

技術的に可能です。
これは実際にはハックのようなもので、プロダクションコードでこのような習慣を避けるべきです。

例:

import java.lang.reflect.Constructor; 
import java.lang.reflect.InvocationTargetException; 

class Example { 

    public void outerMethod() { 

     class InnerClass { 

      private double d = 7.62; 

      @Override 
      public String toString() { 
       return String.format("[%s] d = %f", this.getClass().getName(), d); 
      } 

     } 

    } 

    public void testMethod() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { 

     final Class<?> clazz = Class.forName("Example$1InnerClass"); 
     final Constructor<?> constructor = clazz.getDeclaredConstructor(Example.class); 
     constructor.setAccessible(true); 
     final Object instance = constructor.newInstance(this); 

     System.out.println(instance); 
    } 

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { 
     Example instance = new Example(); 
     instance.testMethod(); 
    } 

} 

ここでは、最初に自分の名前で私たちの地域のクラスのClass<?>を取得します。
ローカルクラス名生成規則は、コンパイラの実装の詳細であり、変更される可能性があります。 AFAIK javacおよびECJは異なるアプローチを使用します。
次に、リフレクションによって興味のあるクラスのコンストラクタを取得します。
クラスはコンストラクタを明示的に定義していないため、コンパイラは自動的に生成します。このコンストラクタはpublicではありません。ここではgetDeclaredConstructor()メソッドを使用します。
このクラスは静的ではないため(ローカルクラスは静的に定義できません)、コンストラクタの最初と唯一のパラメータは外部クラス参照です。我々の場合はExampleです。
その後、constructor.newInstance(this)
thisを呼び出してクラスのインスタンスを作成し、コンストラクタに渡します。コンストラクタパラメータについては上記の注を参照してください。

は最後に、我々は、暗黙的にメソッド内でクラスを定義するための唯一の理由は正確にそのメソッドにその範囲を制限することですInnerClass::toString()

+0

本当にありがとう、これは私が知る必要があるものです。 –

+0

私はEclipseで表現された例を試してみましたが、それは動作します(名前付け規則に少しの変更を加えて) –

+0

この答えを解決策としてマークすることができます。 – user882813

関連する問題