java.lang.NoSuchFieldException:使用反射时

时间:2010-01-08 08:40:12

标签: java reflection

public static <A, B> B convert(A instance,
                           Class<B> targetClass) throws Exception {
  B target = (B)targetClass.newInstance();

  for (Field targetField : targetClass.getDeclaredFields()) {
    targetField.setAccessible(true);
    Field field =
        instance.getClass().getDeclaredField(targetField.getName());
    field.setAccessible(true);
    targetField.set(target, field.get(instance));
  }
  return target;
}

以上是我从论坛获得的代码,当我尝试反映单个类型对象时,它起作用,但是当我尝试复杂类型时,ClassA我得到了ClassB对象,我得到java.lang.NoSuchFieldException。任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:3)

您有两个不同的类,很可能是不同的字段集。 因此,如果您的班级A与您的班级B没有相同的字段,则会抛出异常。

我建议使用BeanUtils.copyProperties(source, target)中的apache commons-beanutils。您只需自己创建第二个对象,然后将其传递给方法。如果字段不同,它不会抛出异常。

这段代码的最终目标是什么?

答案 1 :(得分:1)

两个建议:

(1)您可以在方法的第一行放弃向下转换:

B target = targetClass.newInstance();

(2)添加一个try catch,以便您可以看到缺少字段的名称。这将帮助您理清您遇到的问题:

 Field field = null;
 try {
    field = instance.getClass().getDeclaredField(targetField.getName());
 }
 catch(NoSuchFieldException e) {
     throw new RuntimeException("Didn't find field named '" + targetField.getName() + "'");
 }
 ...

答案 2 :(得分:0)

另一个答案。

如果我理解你的评论,你似乎有内部类:B类(目标)是在A类中定义的类。像这样:

 class A {
   int n;

   class B { 
      int n;
   }
}

虽然这两个类似乎有相同的字段,因此 - 不应该在字段中找不到错误 - 但它们不是。

内部类(除非它们被定义为静态)具有由编译器插入的隐藏字段。此字段属于外部类的类型,并指向创建内部类对象的对象。使用反射时,此字段将被暴露。由于A没有这样的字段,因此会引发异常。