Рефлексивный доступ к статической переменной в классе Java - PullRequest
3 голосов
/ 11 августа 2009

У меня не было другого выбора, кроме как получить доступ к набору классов, которые я не могу изменить, с помощью этой структуры через отражение. Однако, используя метод, показанный ниже в методе main, генерируется исключение NullPointerException. При вызове f1.get (null) нулевой указатель является «таблицей» в конструкторе.

Я не могу создать экземпляры классов заранее, потому что показан только один конструктор, который является закрытым. Поэтому я не могу явно установить таблицу.

Кто-нибудь знает, как я могу рефлексивно назвать Легаси. А?

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);    
    }
}

В до "Отражение == ПЛОХО !!!"

Ответы [ 3 ]

7 голосов
/ 11 августа 2009

Порядок статических инициализаторов неправильный, таблица должна быть до вызова конструктора.

По этой причине вы получаете исключение, когда класс загружается и инициализируется. Это не имеет ничего общего с отражением.

4 голосов
/ 11 августа 2009

Так как это сбивает с толку, я бы написал так:

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);        
        }
}

Таким образом, даже если члены меняют местоположение (из-за рефакторинга, выравнивания строк или чего-либо еще), код всегда будет работать.

0 голосов
/ 11 августа 2009

Я попробовал это, потому что не мог понять, что не так с вашим примером. Это сработало, если я переупорядочил объявления:

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 );
    }
}

Статическим объявлениям нужен (предыдущий) конструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...