如果下面的语句被调用数千次,那么如果有许多类没有名为' id'的字段,那么它将非常慢。有没有办法通过使用java中的反射获取字段,如果字段不存在则不会抛出异常?
Field f2 = null;
try{
f2 = classThatMightNotHaveFieldId.getClass().getDeclaredField("id");
f2.setAccessible(true);
}catch(Exception e){
System.out.println(f1.get(classThatMightNotHaveFieldId));
}
答案 0 :(得分:1)
查看以下类getDeclaredField()
方法的定义:
public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException {
据此,它可以抛出以上两个例外。现在,看一下实现:
if (field == null) {
throw new NoSuchFieldException(name);
}
所以,它会抛出一个异常的字段未找到。如果我们想要压缩它,我们将不得不使用FieldUtils类的Apache commons库,如果找不到字段则返回null,例如:
class Test3{
private int field1;
}
public class Test {
public static void main(String[] args) throws Exception {
Test3 test3 = new Test3();
Field declaredField = FieldUtils.getDeclaredField(Test3.class, "field1", true);
Field declaredField2 = FieldUtils.getDeclaredField(Test3.class, "field2", true);
System.out.println(declaredField);
System.out.println(declaredField2);
}
}
此示例为第一个字段打印hashCode,为第二个字段打印null。
答案 1 :(得分:1)
回答您是否有可能找到没有抛出异常的字段的具体问题:是的,您可以调用Class.getDeclaredFields()
来获取该类的所有字段,然后遍历它们以找到一个适当的名称:
for (Field field : clazz.getDeclaredFields()) {
if (field.getName().equals("id")) {
// Do whatever.
break;
}
}
应该注意的是,虽然这不会引发异常,但它并不比仅仅调用class.getDeclaredField("id")
并吞噬异常更快(并且通常更慢)(通过非常粗略的微基准测试)。 clazz.getDeclaredFields()
在返回之前制作防御的字段副本,因此在调用此方法时还有很多额外的工作要做。
您未在问题中提供实际使用模式的详细信息;您应该进行一些实验,看看是否可以通过现有实现的替代方法实现加速(如某种缓存)。