getClass()上的NoSuchFieldException.getField()

use*_*029 6 java

java.lang.NoSuchFieldException: id
Run Code Online (Sandbox Code Playgroud)

以下行正在创建例外.

String fieldValue =String.valueOf(studyplanCategory.getClass().getField(filterProperty).get(studyplanCategory)); 
Run Code Online (Sandbox Code Playgroud)

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

Per*_*ion 20

的JavadocClass.getField(...):

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

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

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

studyplanCategory.getClass().getField(filterProperty)
Run Code Online (Sandbox Code Playgroud)

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

studyplanCategory.getClass().getDeclaredField(filterProperty)
Run Code Online (Sandbox Code Playgroud)

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

Field field = studyplanCategory.getClass().getDeclaredField(filterProperty);
field.setAccessible(true);
field.get(studyplanCategory);
Run Code Online (Sandbox Code Playgroud)


Sim*_*iak 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));  

...
Run Code Online (Sandbox Code Playgroud)

因此,此列表仅模拟真实数据库.如果你想使用它.所以你应该在支持bean类上做这件事并且做到了.您已经使用某个过滤器打开了连接,或者没有,然后从数据库返回数据.

//编辑:Man写道你应该使用getDeclaredField()但我确实尝试了这个并且它运行不正常,并抛出了IlegalAccessException.当pretype属于受保护时,它工作正常.我不知道为什么.