2017-12-12 6 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

현재 자바 코드로 작동하는 도구를 개발 중입니다. 그래서 도구가 자동으로 내부 클래스의 위치를 ​​변경하면 코드의 핵심을 깨뜨릴 수 있는지 알아야합니다. –

+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 javacECJ은 다른 접근 방식을 사용합니다.
그러면 리플렉션을 통해 관심 클래스의 생성자를 얻습니다.
클래스는 생성자를 명시 적으로 정의하지 않으므로 컴파일러는 자동으로 생성하며이 생성자는 public이 아닙니다. 그래서 여기서 getDeclaredConstructor() 방법을 사용합니다.
이 클래스는 정적이 아니기 때문에 (로컬 클래스는 정적으로 정의 될 수 없습니다) 생성자의 첫 번째 매개 변수와 유일한 매개 변수는 외부 클래스 참조입니다. 우리의 경우 Example.
그런 다음 constructor.newInstance(this)
을 호출하여 클래스의 인스턴스를 생성하는 것은 생성자에 매개 변수로 전달됩니다. 생성자 매개 변수에 대해서는 위의 설명을 참조하십시오.

마지막으로, 우리는 단지 암시 적 방법의 범위를 정확하게하는 방법을 제한하는 내부 클래스를 정의하는 InnerClass::toString()

+0

대단히 고마워.이게 내가 정확히 알아야 할거야. –

+0

Eclipse에서 표현 된 예제를 시도해 보았습니다. (명명 규칙을 약간 변경하여) –

+0

이 답변을 해결책으로 표시 할 수 있습니다. – user882813