2009-08-10 8 views
3

나는 수정할 수없는 클래스 세트에 액세스 할 수밖에 없었습니다.이 구조는 리플렉션을 통해 구현되었습니다. 그러나 아래의 main 메서드에 표시된 메서드를 사용하면 NullPointerException이 throw됩니다. f1.get (null)이 호출 될 때 생성자의 "table"인 널 포인터.Java 클래스의 정적 변수에 반사 식으로 액세스

유일한 생성자가 개인 전용이므로 생성자를 미리 인스턴스화 할 수 없습니다. 그래서 명시 적으로 테이블을 설정할 수있는 방법이 없습니다.

누구든지 나를 레거시라고 부를 수있는 방법을 알고 있습니다 .A?

public class Legacy { 
    public static final Legacy A = new Legacy("A"); 
    public static final Legacy B = new Legacy("B"); 

    private String type0; 
    private static Map<String, Legacy> table = new HashMap<String, Legacy>(); 

    private Legacy(String id) { 
     type0 = id; 
     table.put(type0, this); 
    } 

    public static void main(String[] args) throws Exception { 
     Field f1 = Legacy.class.getDeclaredField("A"); 
     Object o = f1.get(null);  
    } 
} 

"Reflection == BAD !!!"

+0

실제로 NPE, 반향 여부에 관계없이 레거시에 액세스 할 수있는 방법은 없습니다. (리플렉션 코드를 'Object o = Legacy.A'로 교체하십시오.) 코드를 실행하려고 시도했을 때 클래스 초기화 중에 예외가 발생했습니다. – kdgregory

+0

이것은 저장시 자동 포맷 된 코드로 얻은 것입니다. – Andrew

답변

7

정적 초기화 프로그램의 순서가 잘못되었습니다. 생성자가 호출하기 전에 테이블을 가져와야합니다.

이 때문에 클래스가로드되고 초기화 될 때 예외가 발생합니다. 이것은 반성과는 아무런 관련이 없습니다.

0

나는 당신의 예제에 무엇이 잘못되었는지를 알 수 없기 때문에 이것을 시도했다. 선언을 재정렬하면 작동합니다.

import java.lang.reflect.Field; 
import java.util.HashMap; 
import java.util.Map; 

public class Legacy { 
    private String type0; 
    private static Map< String, Legacy > table = new HashMap< String, Legacy >(); 

    private Legacy(String id) { 
     type0 = id; 
     table.put(type0, this); 
    } 
    public static final Legacy A = new Legacy("A"); 
    public static final Legacy B = new Legacy("B"); 

    public static void main(String[] args) throws Exception { 
     Field f1 = Legacy.class.getDeclaredField("A"); 
     Object o = f1.get(null); 
    } 
} 

정적 선언에는 (앞의) 생성자가 필요합니다. 이 혼란 때문에

4

,이처럼 작성합니다

public class Legacy { 
     static { 
      table = new HashMap<String, Legacy>(); 
      A = new Legacy("A"); 
      B = new Legacy("B"); 
     } 

     public static final Legacy A; 
     public static final Legacy B; 

     private String type0; 
     private static Map<String, Legacy> table; 

     private Legacy(String id) { 
       type0 = id; 
       table.put(type0, this); 
     } 

    public static void main(String[] args) throws Exception { 
       Field f1 = Legacy.class.getDeclaredField("A"); 
       Object o = f1.get(null);   
     } 
} 

이 방법을, 구성원 (때문에 리팩토링, 라인 정렬 또는 무엇이든에) 위치를 변경하는 경우에도 코드가 항상 작동합니다.

관련 문제