Java JDK 8 IndexedPropertyDescriptor自JDK 7使用List对象以来已发生更改
我有一个简单的问题。我有一个在JavaJDK7中工作的程序,但由于一些内省更改,它在JDK8中不工作 以下是重现问题的测试程序:Java JDK 8 IndexedPropertyDescriptor自JDK 7使用List对象以来已发生更改,java,java-8,java-7,introspection,Java,Java 8,Java 7,Introspection,我有一个简单的问题。我有一个在JavaJDK7中工作的程序,但由于一些内省更改,它在JDK8中不工作 以下是重现问题的测试程序: import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws IntrospectionException {
BeanInfo info = Introspector.getBeanInfo(MyListClass.class);
PropertyDescriptor[] descriptors = info.getPropertyDescriptors();
for (int i = 0; i < descriptors.length; i++) {
System.out.println(descriptors[i].getClass().getName() + ":" + descriptors[i].getName());
}
System.out.println("\n");
BeanInfo info2 = Introspector.getBeanInfo(MyIndexedListClass.class);
PropertyDescriptor[] descriptors2 = info2.getPropertyDescriptors();
for (int i = 0; i < descriptors2.length; i++) {
System.out.println(descriptors2[i].getClass().getName() + ":" + descriptors2[i].getName());
}
System.out.println("\n");
BeanInfo info3 = Introspector.getBeanInfo(MyArrayClass.class);
PropertyDescriptor[] descriptors3 = info3.getPropertyDescriptors();
for (int i = 0; i < descriptors3.length; i++) {
System.out.println(descriptors3[i].getClass().getName() + ":" + descriptors3[i].getName());
}
System.out.println("\n");
BeanInfo info4 = Introspector.getBeanInfo(MyIndexedArrayClass.class);
PropertyDescriptor[] descriptors4 = info4.getPropertyDescriptors();
for (int i = 0; i < descriptors4.length; i++) {
System.out.println(descriptors4[i].getClass().getName() + ":" + descriptors4[i].getName());
}
}
public class MyListClass {
private List<String> myListClass = new ArrayList<String>();
public List<String> getMyListClass() {
return myListClass;
}
public void setMyListClass(List<String> myListClass) {
this.myListClass = myListClass;
}
}
public class MyIndexedListClass {
private List<String> myIndexedListClass = new ArrayList<String>();
public String getMyIndexedListClass(int index) {
return myIndexedListClass.get(index);
}
public void setMyIndexedListClass(int index, String element) {
this.myIndexedListClass.set(index, element);
}
public List<String> getMyIndexedListClass() {
return myIndexedListClass;
}
public void setMyIndexedListClass(List<String> myIndexedListClass) {
this.myIndexedListClass = myIndexedListClass;
}
}
public class MyArrayClass {
private String[] myArrayClass = new String[20];
public String[] getMyArrayClass() {
return myArrayClass;
}
public void setMyArrayClass(String[] myArrayClass) {
this.myArrayClass = myArrayClass;
}
}
public class MyIndexedArrayClass {
private String[] myIndexedArrayClass = new String[20];
public String getMyIndexedArrayClass(int index) {
return myIndexedArrayClass[index];
}
public void setMyIndexedArrayClass(int index, String myValue) {
this.myIndexedArrayClass[index] = myValue;
}
public String[] getMyIndexedArrayClass() {
return myIndexedArrayClass;
}
public void setMyIndexedArrayClass(String[] myIndexedArrayClass) {
this.myIndexedArrayClass = myIndexedArrayClass;
}
}
}
以下是JDK8的日志:
java.beans.PropertyDescriptor:class
java.beans.PropertyDescriptor:myListClass
java.beans.PropertyDescriptor:class
java.beans.PropertyDescriptor:myIndexedListClass -> Here is the change
java.beans.PropertyDescriptor:class
java.beans.PropertyDescriptor:myArrayClass
java.beans.PropertyDescriptor:class
java.beans.IndexedPropertyDescriptor:myIndexedArrayClass
我必须很快使用JDK8,但这是一个阻碍性的改变,因为我的应用程序不再工作了。我对扩展集合接口(列表、映射等)的所有类都有这个问题
该代码由Apache commons中的库commons-beanutils-1.8.0
使用
我正在寻找一种解决方案,一种变通方法,使我的应用程序在使用JDK7时能够像以前一样工作,有什么解决方案吗?我不能用数组代替列表(因为数组没有改变)
以下是官方文件的链接:
JDK7:
JDK8:
编辑:我找到了解决方案,我的问题与struts 1.3有关。我必须在ActionForm中重命名索引的getter/setter:
好吧,规范明确指出,IndexedPropertyDescriptor
可能有其他基于数组的访问器方法,没有其他方法。这一点没有改变。这里有一些相互冲突的属性方法,它们定义了一个简单的列表
类型化属性和一个同名的索引字符串
属性。基于列表的方法从未与索引属性关联
因此,改变的是哪些冲突属性使其成为BeanInfo
,哪些将被删除。此行为可能取决于HashMap
或类似对象的未指定顺序。可能还有其他因素。因此,不要将其视为Java 7与Java 8之间的问题,而只是一种依赖于实现的行为,这种行为也可能在不同的Java 7实现之间发生变化
有两种方法可以解决这个问题。您可以通过重命名以下属性之一来解决冲突:
public class MyIndexedListClass {
private List<String> myIndexedListClass = new ArrayList<String>();
public String getMyIndexedListClass(int index) {
return myIndexedListClass.get(index);
}
public void setMyIndexedListClass(int index, String element) {
this.myIndexedListClass.set(index, element);
}
public List<String> getMyIndexedListClassAsList() {
return myIndexedListClass;
}
public void setMyIndexedListClassAsList(List<String> myIndexedListClass) {
this.myIndexedListClass = myIndexedListClass;
}
}
我看不出你的例子有什么不同。到底是什么问题?在JDK 7中,BeanInfo的getPropertyDescriptor方法为MyIndexedListClass类返回'IndexedPropertyDescriptor',在JDK 8中返回'PropertyDescriptor'。
public class MyIndexedListClass {
private List<String> myIndexedListClass = new ArrayList<String>();
public String getMyIndexedListClass(int index) {
return myIndexedListClass.get(index);
}
public void setMyIndexedListClass(int index, String element) {
this.myIndexedListClass.set(index, element);
}
public List<String> getMyIndexedListClassAsList() {
return myIndexedListClass;
}
public void setMyIndexedListClassAsList(List<String> myIndexedListClass) {
this.myIndexedListClass = myIndexedListClass;
}
}
public class MyIndexedListClass {
private List<String> myIndexedListClass = new ArrayList<String>();
public String getMyIndexedListClass(int index) {
return myIndexedListClass.get(index);
}
public void setMyIndexedListClass(int index, String element) {
this.myIndexedListClass.set(index, element);
}
public List<String> getMyIndexedListClass() {
return myIndexedListClass;
}
public void setMyIndexedListClass(List<String> myIndexedListClass) {
this.myIndexedListClass = myIndexedListClass;
}
}
static // in your example all classes are inner classes
public class MyIndexedListClassBeanInfo extends SimpleBeanInfo {
private PropertyDescriptor[] properties;
public MyIndexedListClassBeanInfo() throws IntrospectionException {
PropertyDescriptor[] p=Introspector.getBeanInfo(MyIndexedListClass.class,
Introspector.IGNORE_IMMEDIATE_BEANINFO).getPropertyDescriptors();
ArrayList<PropertyDescriptor> list=new ArrayList<>(p.length+1);
for(PropertyDescriptor d: p)
if(!d.getName().equals("myIndexedListClass")) list.add(d);
list.add(new IndexedPropertyDescriptor("myIndexedListClass",
MyIndexedListClass.class, null, null,
"getMyIndexedListClass", "setMyIndexedListClass"));
properties=list.toArray(new PropertyDescriptor[list.size()]);
}
@Override
public PropertyDescriptor[] getPropertyDescriptors() {
return properties;
}
}