Получение значения общедоступного статического конечного поля / свойства класса в Java через отражение

103

Скажем, у меня есть класс:

public class R {
    public static final int _1st = 0x334455;
}

Как я могу получить значение "_1st" через отражение?

Вьетнам
источник
R._1stне может работать? Если вы говорите о разработке под Android, я думаю, что Rкласс всегда рядом ...
Матье
@Matthieu Я тоже так думал, до того дня, когда мне пришлось проделать то же самое, но только с BRклассом.
Севастян Саванюк 08

Ответы:

132

Сначала получите свойство поля класса, затем вы можете получить значение. Если вам известен тип, вы можете использовать один из методов get со значением null (только для статических полей, фактически со статическим полем аргумент, переданный методу get, полностью игнорируется). В противном случае вы можете использовать getType и написать соответствующий переключатель, как показано ниже:

Field f = R.class.getField("_1st");
Class<?> t = f.getType();
if(t == int.class){
    System.out.println(f.getInt(null));
}else if(t == double.class){
    System.out.println(f.getDouble(null));
}...
М. Джессап
источник
Спасибо. Я пробовал, но ничего не вышло. Исключение выбрасывается в операции f.getInt (null). Я поймал это, но почему тут исключение?
Viet
1
Какое исключение вы получили?
М. Джессап
Привет, исключение e.getMessage () возвращает имя поля, которое является «_1st» и ничего больше.
Viet
1
Но что это за исключение? (т.е. NullPointerException, SecurityException, ...)
М. Джессап
2
Почему в документации никогда не упоминается, что getInt()игнорирует переданный аргумент? Потратил часы на попытки передать туда экземпляр класса.
Севастян Саванюк 08
70
 R.class.getField("_1st").get(null);

Обработка исключений оставлена ​​в качестве упражнения для читателя.

В основном вы получаете поле, как и любое другое, через отражение, но когда вы вызываете метод get, вы передаете значение null, поскольку нет экземпляра, с которым можно было бы действовать.

Это работает для всех статических полей, независимо от того, являются ли они окончательными. Если поле не является общедоступным, вам нужно setAccessible(true)сначала вызвать его, и, конечно же, SecurityManager должен разрешить все это.

Ишай
источник
Я понял. На самом деле мне нужен был R.id. Спасибо за вашу помощь!
Viet
1

Я шел по тому же маршруту (просматривая сгенерированный класс R), а затем у меня возникло ужасное ощущение, что это, вероятно, функция в классе ресурсов. Я был прав.

Нашел это: Resources :: getIdentifier

Думал, что это может сэкономить людям время. Хотя в документах говорится, что это обескураживает, что неудивительно.

Брайан
источник
Итак, вы решили, что это вопрос Android. Должно быть указано в тегах ...
Матье
Это не вопрос Android, это вопрос отражения Java, в котором используется конкретный пример. Вопросы помечаются в зависимости от темы.
Мэтью Рид