80

java.lang.NoSuchFieldException在尝试运行以下方法时遇到了问题:

 public void getTimes(String specialty, String day) {
    ArrayList<Tutor> withSpec = new ArrayList<Tutor>();
    for (Tutor t : tutorList){
        try {
            Time startTime = (Time)t.getClass().getField(day + "Start").get(t);
        } catch (NoSuchFieldException | SecurityException | IllegalAccessException ex) Logger.getLogger(DBHandler.class.getName()).log(Level.SEVERE, null, ex); }

错误在线Time startTime = (Time)t.getClass().getField(day + "Start").get(t);

我不明白这个错误,因为 monStart 是Tutor类的一个字段:

Public class Tutor implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "tutorID")
private Integer tutorID;

.... 

@Column(name = "monStart")
@Temporal(TemporalType.TIME)
 Date monStart;

我只是在学习使用反射,所以我确定这是某种语法错误......

4

7 回答 7

167

getField方法只会找到该字段,如果它是public. 您将需要改用该方法,该方法将找到直接getDeclaredField在类上声明的任何字段,即使它不是.public

于 2013-03-14T22:00:12.340 回答
11

根据 javadoc,Class.getField()“返回一个Field对象,该对象反映该对象表示的类或接口的指定公共成员字段Class”。getDeclaredField()如果您想访问非公共字段,请使用。

于 2013-03-14T22:00:27.883 回答
7

问题的最佳解决方案getClass().getField()是:

  1. 使用getDeclaredField () 代替getField ():
        String propertyName = "test";
        Class.forName(this.getClass().getName()).getDeclaredField(propertyName);
  1. “HelloWorld”替换为您的班级名称:
        String propertyName = "name";
        HelloWorld.class.getDeclaredField(propertyName);

如果要获取列的注释长度:

HelloWorld.class.getDeclaredField(propertyName).getAnnotation(Column.class).length();
于 2014-05-07T07:59:16.600 回答
6

对于任何看到此问题但似乎仍无法解决问题的 Android 开发人员,请检查是否启用了 Proguard。如果是这样,则可能是相关类被混淆了,您需要添加规则以防止这种情况发生。

于 2019-08-30T19:37:09.743 回答
2

我是根据标题来回答这个问题的。我在我的 Android 项目中遇到了同样的错误 ( NoSuchFieldException),但原因不同。

所以对于其他来这里的人来说,这个错误也可能是由于 Android Studio 中的缓存不同步造成的。转到文件>使缓存无效/重新启动...

参阅

于 2016-09-13T09:47:15.567 回答
1

如已接受的答案中所述, usinggetDeclaredField可能会解决您的问题(如果该字段未声明为public)。

如果您仍然得到NoSuchFieldException,那可能是因为该字段实际上在超类中!确实,如果你的类是extends另一个类,那么你将不会通过getDeclaredField方法获得继承的字段。以下是解决该问题的方法:

String propertyName = "foo";
yourClass.getClass().getSuperClass().getDeclaredField(propertyName);
于 2021-11-12T17:12:29.223 回答
0

很高兴知道...如果您的班级有 @Configuration,则 getDeclaredFields() 将不包含您的字段。

于 2021-09-01T15:09:58.280 回答