gpt4 book ai didi

Java JDK 8 IndexedPropertyDescriptor 自 JDK 7 以来已更改为 List 对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:22:34 25 4
gpt4 key购买 nike

我有一个简单的问题。我有一个在 Java JDK7 中工作的程序,但由于一些内省(introspection)更改,它在 JDK8 中不起作用。

这是一个重现问题的测试程序:

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

}
}

这是 JDK 7 日志:

java.beans.PropertyDescriptor:class
java.beans.PropertyDescriptor:myListClass

java.beans.PropertyDescriptor:class
java.beans.IndexedPropertyDescriptor:myIndexedListClass

java.beans.PropertyDescriptor:class
java.beans.PropertyDescriptor:myArrayClass

java.beans.PropertyDescriptor:class
java.beans.IndexedPropertyDescriptor: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,但这是一个阻碍性的变化,因为我的应用程序不再工作了。我对所有扩展 Collection 接口(interface)(List、Map、...)的类都有这个问题

该代码由 Apache Commons 的库 commons-beanutils-1.8.0 使用。

我正在寻找一种解决方案,一种变通方法,使我的应用程序像以前一样工作,当使用 JDK7 时,是否有任何解决方案?我不能用 Array 代替 List(因为 Array 没有改变)

官方文档链接如下:

JDK7:http://docs.oracle.com/javase/7/docs/api/java/beans/IndexedPropertyDescriptor.html

JDK8:http://docs.oracle.com/javase/8/docs/api/java/beans/IndexedPropertyDescriptor.html


编辑:我找到了我的解决方案,我的问题与 struts 1.3 有关。我不得不在我的 ActionForm 中重命名我的索引 getter/setter: http://www.coderanch.com/t/55172/Struts/Indexed-Properties

最佳答案

好吧,规范清楚地表明 IndexedPropertyDescriptor可能有额外的基于数组的访问器方法,没有别的。那没有改变。你这里有冲突属性方法定义一个简单的List<String>类型化属性和索引 String同名属性(property)。 List基于方法从未与索引属性相关联。

所以发生变化的是哪些冲突属性进入了 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;
}
}

然后,所有 Java 版本的行为都将相同,但它的副作用是现在将两个不同的属性视为不同命名的属性。


另一种方法是保持方法不变,但显式省略 List基于属性描述符识别的方法。换句话说,使发生在一种实现中并且似乎是您想要的行为明确化。

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

关于Java JDK 8 IndexedPropertyDescriptor 自 JDK 7 以来已更改为 List 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30663238/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com