【问题标题】:Java JDK 8 IndexedPropertyDescriptor has changed since JDK 7 with List objectJava JDK 8 IndexedPropertyDescriptor 自 JDK 7 以来已更改,带有 List 对象
【发布时间】:2015-08-20 05:02:02
【问题描述】:

我有一个简单的问题。我有一个在 Java JDK7 中运行的程序,但由于一些自省更改,它在 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 接口(列表、地图...)的所有类都有这个问题

代码由来自 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

【问题讨论】:

  • 我看不出你的例子有什么不同。究竟是什么问题?
  • 在 JDK 7 中,BeanInfo 的 getPropertyDescriptor 方法为 MyIndexedListClass 类返回“IndexedPropertyDescriptor”,在 JDK 8 中返回“PropertyDescriptor”。

标签: java java-8 java-7 introspection


【解决方案1】:

好吧,规范清楚地表明IndexedPropertyDescriptor 可能有其他基于数组的访问器方法,仅此而已。那没有改变。您在这里拥有的是冲突 属性方法,它们定义了一个简单的List&lt;String&gt; 类型属性和一个同名的索引String 属性。基于 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;
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 2016-06-28
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    相关资源
    最近更新 更多