6
java.lang.NoSuchFieldException: id

下面的行正在创建异常。

String fieldValue =String.valueOf(studyplanCategory.getClass().getField(filterProperty).get(studyplanCategory)); 

studyplanCategory 是一个有效的对象并且有实际的值。由于此异常,我的 JSF webapp 的 LazyLoading DataTable 中的加载方法和搜索功能无法正常工作。

4

4 回答 4

20

来自JavadocClass.getField(...)

返回一个反映此 Class 对象表示的类或接口的指定公共成员字段的 Field 对象。name 参数是一个字符串,指定所需字段的简单名称。要反射的场由下面的算法确定。设 C 为该对象所代表的类:

如果 C 声明了一个具有指定名称的公共字段,那就是要反映的字段。如果在上面的步骤 1 中没有找到任何字段,则该算法递归地应用于 C 的每个直接超接口。直接超接口按照它们被声明的顺序进行搜索。如果在上面的步骤 1 和 2 中没有找到字段,并且 C 有一个超类 S,则在 S 上递归调用此算法。如果 C 没有超类,则抛出 NoSuchFieldException。请参阅 Java 语言规范,第 8.2 和 8.3 节。

如果您尝试通过以下方式检索的字段:

studyplanCategory.getClass().getField(filterProperty)

是私人的,那么你会得到一个NoSuchFieldException. 对于私有字段,请尝试以下操作:

studyplanCategory.getClass().getDeclaredField(filterProperty)

并以这种方式通过字段设置值时绕过潜在的非法访问异常:

Field field = studyplanCategory.getClass().getDeclaredField(filterProperty);
field.setAccessible(true);
field.get(studyplanCategory);
于 2012-04-25T12:44:01.747 回答
9

应用程序会触发此异常,因为它看不到您想要回馈的属性。方法 getField() 返回非私有属性,因此如果您的属性是私有的,则方法看不到它们。您可以查看http://docs.oracle.com/javase/tutorial/reflect/member/fieldTrouble.html

因此,您可以这样做,您的属性将更改为受保护或公开,然后应该正常工作。但是这种方式(与 primefaces 上的示例相同)模拟真实数据库。

public List<Car> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {  
        List<Car> data = new ArrayList<Car>();  

        //filter  
        for(Car car : datasource) {  
            boolean match = true;  

            for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {  
                try {  
                    String filterProperty = it.next();  
                    String filterValue = filters.get(filterProperty);  
                    String fieldValue = String.valueOf(car.getClass().getField(filterProperty).get(car));  

...

因此,此列表仅以模拟真实数据库为例。如果你想使用它。所以你应该在支持 bean 类上做它并在那里做。您已经使用某些过滤器打开连接或不打开连接,然后从数据库返回数据。

//编辑:Man 写道您应该使用 getDeclaredField() 但我确实尝试过,但效果不佳,并引发了 IlegalAccessException。当一个 pretype 归属于 protected 时,它可以正常工作。我不知道为什么。

于 2012-04-25T12:45:39.983 回答
1

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

使用getDeclaredField () 代替getField ()

1)

String propertyName = "test";<br/>
Class.forName(this.getClass().getName()).getDeclaredField(propertyName);

2)

String propertyName = "name";<br/>
Replace **"HelloWorld"** with your class name<br/>
HelloWorld.class.getDeclaredField(propertyName)
于 2014-05-07T07:56:03.270 回答
0

我也遇到过同样的问题。我的问题是我的变量不是public。确保您的类变量是公开的

  private Object getVariableValue(Object clazz, String variableName) {
    try {
        Field field = clazz.getClass().getField(variableName);
        return field.get(clazz);
    } catch (NoSuchFieldException e) {
        return "";
    } catch (IllegalAccessException e) {
        return "";
    }

}
于 2017-03-19T12:34:31.503 回答