java.lang.NoSuchFieldException:使用反射时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2026369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 18:59:45  来源:igfitidea点击:

java.lang.NoSuchFieldException: when using reflection

javareflection

提问by user236501

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;
}

Above is the code I get from forum, When I try to reflect an single type object it works, but when I try on the complex type which mean inside ClassAI got ClassBobject, I got the java.lang.NoSuchFieldException. Can anyone help me?

以上是我从论坛获得的代码,当我尝试反映单个类型的对象时它可以工作,但是当我尝试复杂类型时,这意味着在ClassA我得到ClassB对象时,我得到了java.lang.NoSuchFieldException. 谁能帮我?

回答by Bozho

You have two different classes, with, most likely, different set of fields. So if your Class Adoesn't have the same fields as your class B, then the exception is thrown.

你有两个不同的类,很可能有不同的字段集。因此,如果您的 ClassA与您的 class没有相同的字段B,则会引发异常。

I'd suggest using BeanUtils.copyProperties(source, target)from apache commons-beanutils. You just create the second object yourself, and pass it to the method. It will not throw an exception if fields differ.

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

What is your ultimate goal with this piece of code?

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

回答by Itay Maman

Two suggestion:

两个建议:

(1) You can drop the downcast at the first line of the method:

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

B target = targetClass.newInstance();

(2) Add a try catch so that you can see the name of the missing field. This will help you sort out the issue you're having:

(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() + "'");
 }
 ...

回答by Itay Maman

Another answer.

另一个答案。

If I understand your comment correctly it seems that you have inner classes: Class B (Target) is a class that is defined inside class A. Something like this:

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

 class A {
   int n;

   class B { 
      int n;
   }
}

Although these two classes seem to have the same fields, and therefore - should not inude a field not found error - they are not.

尽管这两个类似乎具有相同的字段,因此 - 不应包含未找到字段的错误 - 它们并非如此。

Inner classes (unless they are defined as static) has a hidden field inserted by the compiler. This field is of the type of the outer class and points to the object that created the inner class object. When using reflection this field is exposed. As A does not have such field, an exception is raised.

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