2013-05-22 31 views
5

Tôi có lớp generic:Java tạo các đối tượng của loại hình chung với không rõ trong tham số loại biên soạn

class Field<T> { } 

Và một số lớp khác (có loại Tôi biết chỉ trong thời gian chạy) với nhiều có được phương pháp ví dụ:

class A{ 
     public Date getDate(); 
     public String getName(); 
     public Integer getNumber(); 
    } 

Tôi muốn tạo các phiên bản của lớp Field cho tất cả các phương thức nhận được, với T tương đương với loại trả về của các phương thức get này. Ví dụ: Field<Date>, Field<String>, Field<Integer>.

Ai đó có thể trợ giúp?

+2

Nếu bạn định thực hiện điều này thông qua phản ánh và khi chạy, loại chung không quan trọng chút nào. Bạn cũng có thể làm điều đó mà không có tham số chung. –

+0

Tôi không hiểu những gì bạn đang cố gắng làm. Viết một ví dụ mã hoàn chỉnh, ngay cả khi nó không biên dịch, minh họa những gì bạn đang cố gắng đạt được. – erickson

+0

Phản ánh không phù hợp với trường hợp sử dụng này. Hãy xem xét sử dụng Introspection trực tiếp phơi bày các phương pháp để có được các getters. –

Trả lời

2

Bạn sử dụng sự phản chiếu thường cho những thứ bạn chỉ biết khi chạy. Thông tin Generics được xóa tại thời gian biên dịch. Vì vậy, trong khi có những trường hợp mà bạn có thể kết hợp cả hai, nó không phải là phổ biến.

Tôi muốn tạo các phiên bản của trường lớp cho tất cả các phương thức nhận được, với T bằng với kiểu trả về của các phương thức get này. Đối với ví dụ này Field, Field, Field.

Để trả lời câu hỏi của bạn theo nghĩa đen:

Field<Date> dateField = new Field<Date>(); 
Field<String> nameField = new Field<String>(); 
Field<Integer> numberField = new Field<Integer>(); 
1

Tôi không tin bạn có thể tạo các kiểu trường chung trong trường hợp này, vì Generics được kiểm tra tại thời gian biên dịch, trong khi bạn chỉ có thể nhận được (thông qua phản ánh) kiểu trả về của các phương thức đã khai báo của lớp A tại thời gian chạy.

+0

cách duy nhất để tạo danh sách cho các lớp không xác định là Danh sách nhưng điều này sẽ không giúp ích nhiều. – pad

1

Để có được thu khí, xem xét sử dụng mẫn hơn là phản ánh: nó được thiết kế cho mục đích này!

Dưới đây là mã để tự động nhận được các getters. Hãy cẩn thận, bạn cũng nhận được getClass() "getter!

for(PropertyDescriptor descriptor :Introspector.getBeanInfo(A.class).getPropertyDescriptors()){ 
    System.out.println("Getter method :" + descriptor.getReadMethod()); 
    System.out.println("Return type : " + descriptor.getReadMethod().getReturnType()); 
    Class<?> c=descriptor.getReadMethod().getReturnType(); 
} 

}

Output:

Getter method :public final native java.lang.Class java.lang.Object.getClass() 
Return type : class java.lang.Class 
Getter method :public java.util.Date A.getDate() 
Return type : class java.util.Date 
Getter method :public java.lang.String A.getName() 
Return type : class java.lang.String 
Getter method :public java.lang.Integer A.getNumber() 
Return type : class java.lang.Integer 

Sau đó, bạn có thể dễ dàng tạo ra một lĩnh vực cho mỗi người trong số những người thu khí. Đối với loại chung chung, nó không thực sự có ý nghĩa trong thời gian chạy nhưng nó vẫn còn có thể sử dụng điều này trong một bộ tạo mã ...

+0

Hoặc sử dụng Commons Beanutils. –

2
class Field<T> { 
    T value; 
    Field(T value) {this.value = value;} 
} 


class A{ 
    Date date; 
    public Field<Date> getDate() { 
     return new Field<Date>(date); 
    } 

    //etc.... 
} 

Hãy suy nghĩ về Generics như chú thích trình biên dịch thay vì kiểm tra kiểu thời gian chạy thực tế. Mã được biên dịch sẽ đơn giản có các phôi tĩnh và không thực hiện bất kỳ kiểm tra kiểu chung nào cả. Các tính năng generics chỉ là loại tacked vào trình biên dịch để cung cấp khả năng tương thích thời gian chạy với JVM cũ hơn, bằng cách sử dụng những gì Sun gọi là, "Loại Erasure". Dưới đây là một số đọc tốt về nó:

http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

Các vấn đề liên quan