2015-01-01 5 views
0

Eclipse에서 Java 반영 숙제를 디버깅하는 동안 이상한 동작이 발생합니다. 는 I 2 개 클래스 정의 : 내 프로그램의 어느 시점에서 Java 리플렉션을 사용하여 내부 클래스에서 중첩 클래스의 필드 수정

public class OuterClass{ 
    protected Person person; 

    public void aPerson(Integer age) { 
     person = new Person(age); 
    } 
} 

public class OuterDerivedClass extends OuterClass { 

    public class InnerClass extends OuterClass { 

     public void aPerson(Integer age) { 
      person = new Person(age); 
     } 
    } 
} 

, 내 프로그램이 에 어떤 클래스를 작동하도록되어 정도로 (반사를 사용하여 같은 InnerClass의 인스턴스를 인스턴스화 된 상자의 클래스 정적이 될 수 있습니다./비 정적 및 공공/민간 /) 보호 :

method.invoke(inner_instance, parameter); 
: 나중에 나에

Class<?> outer_class = outer_instance.getClass(); 
Constructor<?> ctor = inner_class.getDeclaredConstructor(outer_class); 
Object inner_instance = ctor.newInstance(outer_instance); 

은 OuterDerivedClass $ InnerClass.aPerson 방법을 호출

지금까지는 모든 것이 정상적으로 보였습니다. inner_instance가 성공적으로 작성되었으며, 올바른 aPerson 메소드 (InnerClass의 메소드)가 호출되었습니다. 그러나 나중에 내 프로그램에서 outer_instance에서 person 필드에 액세스하려고 시도했지만 NULL이 아니라는 것을 알아 냈습니다 (aPerson 메서드에서 만들어 졌음에도 불구하고). 이클립스에서 디버깅하는 동안, 나는 이것을 발견 :

(내 질문에 PersonStoryDerivedTest == OuterDerivedClass)

enter image description here

.

이 $ 0의 ID는 생성자 (outer_instance)에 보낸 ID와 동일합니다. 두 번째 사람 필드가 무엇인지 알아낼 수 없었습니다 (aPerson을 호출하여 분명히 생성 된 필드). 이 필드는 중첩 클래스에만 존재해야합니까? 내 의도는 OuterDerivedClass $ InnerClass.aPerson의 호출은 outer_instance의 사람 필드를 변경한다는 것이 었습니다 (이것이 처음에 생성자에게 전송 된 이유라고 생각했습니다).

누군가 이러한 문제를 명확히 할 수 있습니까? 감사!

+1

나는이 권리를 이해한다면, 귀하의 질문에 왜 '사람 = 새로운 사람 (나이)'집합'this.person'하지에 관한 것입니다 'OuterDerivedClass.this.person'? 모든 반향 내용은 관련성이 없습니다 (반향없이 수행하는 경우에도 동일한 문제가 발생합니다). – immibis

+0

getter 답변을 더 빨리 얻으려면 [SSCCE] (http://sscce.org/)를 포함하도록 질문을 편집하십시오. 귀하의 질문에 현재 쓰여진대로 'testInstance'와 같은 혼동을 일으키는 부분이 거의없고'inner_instance' 대신'method.invoke (testInstance, parameter);에 사용 된 이유는 무엇입니까? 귀하의 모범을 짧게 만드십시오, 그러나 완전히 편집하십시오. – Pshemo

+0

@immibis가 주요 질문입니다. 콘크리트 클래스에 액세스하는 데 문제가있어서 (클래스 객체로 전달됨) 반영하지 않고 시도하지 않았습니다. – boaz88

답변

0

내가

public class InnerClass extends OuterClass { 
//      ^^^^^^^^^^^^^^^^^^ 

이후, 두 번째 사람 필드

음이 무엇인지 알아낼 수없는 당신의 InnerClass 또한

public void aPerson(Integer age) { 
    person = new Person(age); 
} 
로 설정되어 자신의 person 필드를 상속

personthis.person이고이 메소드 내부의 this은 메소드가 구현 된 클래스의 인스턴스 (InnerClass에서)를 나타냅니다.

당신은 당신의 방법은 당신이 OuterDerivedClass.this.person 통해 참조 할 필요가 OuterClass#person 필드를 초기화하려면,하지만이 InnerClass의 초기화되지 않은 person 경기장을 떠나지 않습니다.

기타 (간단) 옵션은 InnerClass에서 OuterClass 연장되지 않습니다

public class InnerClass{ 
+0

와우. 5 시간 동안 코드를 쳐다 보았지만 (또는 아마) 그 부분을 완전히 놓쳤습니다. 감사! – boaz88

+0

@ boaz88 환영합니다 :) – Pshemo

관련 문제