Отримання значення загальнодоступного статичного кінцевого поля / властивості класу на Java за допомогою відображення


103

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

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

Як я можу отримати значення "_1st" за допомогою відображення?


R._1stне міг працювати? Якщо ви говорите про розробку Android, я думаю, Rклас завжди є ...
Matthieu

@Matthieu Я теж так думав, до цього дня, коли мені довелося робити це саме те саме, але тільки з BRкласом.
Севастьян Саванюк

Відповіді:


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). Я спіймав це, але як виникла виняток?
В'єт

1
Який виняток ви отримали?
М. Джессуп

Привіт, виняток e.getMessage () повертає ім'я поля, яке є "_1st" і нічого іншого.
В'єт

1
Але який тип винятку? (тобто NullPointerException, SecurityException, ...)
M. Jessup

2
Чому документація ніколи не згадує про те, що getInt()ігнорує переданий аргумент? Витратили години на спроби змусити екземпляр класу пройти туди.
Саванюк Саванюк

70
 R.class.getField("_1st").get(null);

Поводження з винятками залишається вправою для читача.

В основному ви отримуєте поле, як і будь-яке інше за допомогою відображення, але, коли ви викликаєте метод get, ви переходите в нуль, оскільки немає жодного примірника для дії.

Це працює для всіх статичних полів, незалежно від того, чи є вони остаточними. Якщо поле не є загальнодоступним, setAccessible(true)спочатку потрібно зателефонувати , і, звичайно, SecurityManager повинен дозволити все це.


Зрозумів. Клас, який мені був потрібний, був насправді R.id. Спасибі за вашу допомогу!
В'єт

1

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

Виявив це: Ресурси :: getIdentifier

Думав, що це може врятувати людей деякий час. Хоча кажуть, що це відволікає у документах, що не надто дивно.


Отже, ви зробили висновок, що це питання для Android. Повинні були бути вказані в тегах ...
Матьє

Це не запитання щодо Android, це питання відображення Java, яке використовує конкретний приклад. Питання позначені тегами залежно від їх теми.
Матвій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.