2015-06-05 23 views
7

Tôi có một vấn đề đơn giản. Tôi có một chương trình làm việc trong Java JDK7 nhưng nó không hoạt động trong JDK8 vì một số thay đổi nội tâm.Java JDK 8 IndexedPropertyDescriptor đã thay đổi kể từ JDK 7 với đối tượng List

Đây là một chương trình thử nghiệm để tạo lại vấn đề:

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

    } 
} 

Dưới đây là JDK 7 bản ghi:

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 

Dưới đây là các bản ghi cho 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 

tôi phải sử dụng JDK8 rất sớm nhưng đây là một thay đổi chặn vì ứng dụng của tôi không hoạt động nữa. Tôi gặp vấn đề này với tất cả các lớp mở rộng giao diện Collection (Danh sách, Bản đồ, ...)

Mã này được sử dụng bởi thư viện commons-beanutils-1.8.0 từ Apache Commons.

Tôi đang tìm một giải pháp, một giải pháp khác, để làm cho ứng dụng của tôi hoạt động giống như trước đây, khi sử dụng JDK7, có giải pháp nào không? Tôi không thể sử dụng mảng thay vì List (vì mảng đã không thay đổi)

Sau đây là các liên kết đến các tài liệu chính thức:

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


EDIT: Tôi tìm thấy giải pháp của tôi, vấn đề của tôi có liên quan với struts 1.3. Tôi đã phải đổi tên getter được lập chỉ mục của tôi/setter trong ActionForm của tôi: http://www.coderanch.com/t/55172/Struts/Indexed-Properties

+0

Tôi thấy không có sự khác biệt trong ví dụ của bạn. Chính xác thì vấn đề là gì? –

+1

Trong JDK 7, phương thức getPropertyDescritor của BeanInfo trả về 'IndexedPropertyDescriptor' cho lớp MyIndexedListClass và trong JDK 8 trả về một 'PropertyDescriptor'. –

Trả lời

5

Vâng, đặc điểm kỹ thuật nói rõ rằng một IndexedPropertyDescriptor có thể có phương pháp accessor mảng bổ sung dựa, không có gì khác. Điều đó đã không thay đổi. Những gì bạn có ở đây là xung đột các phương thức thuộc tính xác định thuộc tính được nhập đơn giản List<String> và thuộc tính được đánh chỉ mục String có cùng tên. Các phương pháp dựa trên List không bao giờ được liên kết với thuộc tính được lập chỉ mục.

Vì vậy, những gì đã thay đổi là thuộc tính xung đột làm cho nó rơi vào số BeanInfo và sẽ bị xóa. Hành vi này có thể phụ thuộc vào thứ tự không xác định của HashMap hoặc giống như vậy. Cũng có thể có các yếu tố khác. Do đó, không thấy nó như là một vấn đề Java 7 so với Java 8, nhưng chỉ là một hành vi phụ thuộc triển khai thực hiện cũng có thể thay đổi giữa các triển khai Java 7 thay thế.

Có hai cách để giải quyết vấn đề này. Bạn có thể giải quyết xung đột bằng cách đổi tên một trong những thuộc tính:

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

Sau đó, tất cả các phiên bản Java sẽ cư xử như nhau, nhưng nó có tác dụng phụ bây giờ nhìn thấy hai thuộc tính khác nhau như khác nhau đặt tên thuộc tính.


Cách khác là giữ nguyên phương pháp nhưng rõ ràng là phương pháp dựa trên nhận dạng mô tả thuộc tính.Nói cách khác, thực hiện hành vi, đã xảy ra trong một lần thực hiện và dường như là hành vi mong muốn của bạn, rõ ràng.

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; 
    } 
} 
Các vấn đề liên quan