通过反射获取Java类的公共静态最终字段/属性的价值


103

说我有一堂课:

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

如何通过反射获取“ _1st”的值?


R._1st无法工作?如果您在谈论Android开发,我认为R课程总是存在的……
Matthieu 2015年

@Matthieu我也这么认为,直到今天我不得不做同样的事情,但仅限于BR课堂上。
Sevastyan Savanyuk

Answers:


132

首先检索类的field属性,然后可以检索值。如果知道类型,则可以使用带null的get方法之一(仅对于静态字段,实际上对于静态字段,传递给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
您收到了哪种例外?
M. Jessup

嗨,异常e.getMessage()返回字段名称,该字段名称是“ _1st”,除此之外没有其他内容。
越南

1
但是异常的类型是什么?(即NullPointerException,SecurityException等)
M. Jessup

2
为什么文档从未提及getInt()忽略传入的参数?花费了几个小时尝试将类的实例传递到那里。
Sevastyan Savanyuk

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

异常处理留给读者练习。

基本上,您可以通过反射像其他任何字段一样获取该字段,但是当您调用get方法时,由于没有实例可操作,因此传入了null。

这适用于所有静态字段,无论它们是最终字段。如果该字段不是公共字段,则需要先对其进行调用setAccessible(true),当然SecurityManager必须允许所有这些。


我知道了。我需要的课程实际上是R.id。谢谢你的帮助!
越南

1

我遵循相同的路线(浏览生成的R类),然后我感到可怕的是它可能是Resources类中的一个函数。我是对的。

找到以下内容: Resources :: getIdentifier

认为这可以节省一些时间。尽管他们在文档中不建议这样做,但这并不奇怪。


因此,您推断这是一个Android问题。应该已经在标签中指明了…
Matthieu

这不是一个Android问题,而是一个使用特定示例的Java反射问题。根据主题对问题进行标记。
马修(Matthew)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.