2011-09-01 1 views
0

이상한 결과가 나옵니다. Java의 버그인지 또는 예상되는 동작인지 확실하지 않습니다. 선언 된 필드 (class.getDeclaredFields())를 가져 오기 위해 리플렉션을 사용하는 내부 클래스가 있습니다. 그러나 필드 목록을 반복하고 개별 유형을 확인하면 "this"필드가 inner 클래스가 아닌 outerclass를 반환합니다.JDK6의 내부 클래스에서 "this"의 필드 유형이 잘못 되었습니까?

이 예상되는 동작입니까? 나에게 꽤 이상한 것 같습니다.

예 :

import java.lang.reflect.Field; 

public class OuterClass { 

    public class InnerClass{ 
     public String innerClassString; 
      public InnerClass innerClass; 

    } 


    public static void main(String[] args) { 

     // print the fields of the inner class 
     for(Field field : OuterClass.InnerClass.class.getDeclaredFields()) 
      System.out.println(field.getName() + " ::: " + field.getType()); 
    } 
} 

출력 :

innerClassString ::: class java.lang.String 
innerClass ::: class OuterClass$InnerClass 
this$0 ::: class OuterClass 

나는 형 OuterClass.InnerClass 될이 $ 0 예상했다.

이것은 Java 버그입니까? 어쨌든이 예기치 않은 동작을 해결할 수 있습니까?

감사합니다,

에릭

+4

99.99 %, 당신은 꽤 많이는 전 세계 수백만의 개발자에 의해 사용되는 프레임 워크 버그가 아니라고 가정 할 수있다. – StriplingWarrior

+0

동의합니다. 그러나 이전에 비슷한 점을 보았는데이 포인터는 Java7에서 수정 된이 포인터로 버그를 표시하여 궁금해졌습니다. (http://stackoverflow.com/questions/4823278/inner-class-type-parameter-bound-by-enclosing-class-type-variable) –

+0

'this $ 0'은 외부 클래스 객체에 대한 참조입니다. Inner 클래스 객체 자체에 대한 참조가 필요하지 않습니다. 즉 'this' –

답변

9

모든 비 정적 내부 클래스가 인스턴스화 된 외부 클래스에 대한 참조를 보유하고 눈에 보이지 않는 바르를 유지한다. 그게 this$0입니다.

내부 클래스를 public static class으로 변경하고 차이점을 확인하십시오.

http://download.oracle.com/javase/tutorial/java/javaOO/nested.html

용어 : 명확성을 위해

오라클이 용어를 추천 정적 및 비 정적 : 중첩 클래스는 두 종류로 구분된다. 정적으로 선언 된 중첩 클래스은 단순히 정적 중첩 클래스이라고합니다. 비 정적 중첩 클래스내부 클래스이라고합니다.

...

InnerClass의 인스턴스는 OuterClass의 인스턴스 내에 존재 방법 및 포위 인스턴스의 필드에 직접 액세스 할 수있다. ...

내부 클래스를 인스턴스화하려면 먼저 외부 클래스를 인스턴스화해야합니다. 그런 다음이 구문을 사용하여 외부 객체 내에서 내부 객체를 생성 :

OuterClass.InnerClass innerObject = outerObject.new InnerClass(); 

===

원하는 경우이 $ 0 변수에 대한 모든 액세스는 내부 클래스 내에서 다음 거기 ?

내부 클래스의 방법에서, 당신은 말할 수 :

OuterClass outer = OuterClass.this; 

또는

System.out.println(OuterClass.this.toString()); 

의이 특별한 변형 - OuterClass.this - this$0 바르에 액세스 - 그것은 OuterClass 인스턴스를 반환합니다. 이것은 InnerClass 메서드 내에서 일반 this을 사용하는 것과는 다르며 현재 InnerClass 인스턴스를 반환합니다.

===

또한

, 내가 문자열 비교 사용하지 않고 "이 $ 0"으로 필드를 처리하고 만약 내가 확인하는 방법?

나는 무엇을 하려는지 명확하지 않으므로 원하는 것을 성취 할 수있는 방법을 권장 할 수 없습니다.

+0

원하는 경우 내부 클래스에서이 $ 0 변수에 액세스 할 수 있습니까? 또는 숨겨진 변수입니까? 리플렉션 변수를 통해서만 사용할 수 있습니까? 또한 문자열 비교를 사용하지 않고 "this $ 0"필드를 처리할지 여부를 어떻게 결정할 수 있습니까? if (field.getType() == classBeingProcessed.getClass())가 내 코드에서 계속 진행되기를 바랬지 만, 더 이상 가능하지 않습니다. 내 유일한 선택은 다음과 비교되는 문자열입니까? –

+0

자습서가 잘못되었습니다. 정적 컨텍스트 (예 : 정적 메서드)에서 내부 클래스를 가질 수 있습니다. 그런 다음 내부 인스턴스가 없습니다. 클래스의 분류는 꽤 혼란 스럽습니다. – irreputable

관련 문제