2016-03-13 13 views
6

Tôi gặp sự cố khi khởi tạo lớp có tham số kiểu. Nó có vẻ là một thiếu sót của suy luận kiểu Java và tôi muốn biết nếu có một cách xung quanh này hoặc một cách tốt hơn để đạt được điều này.Java - vấn đề khởi tạo lớp với các tham số kiểu

public class ParentModel {} 

public class ChildModel extends ParentModel {} 

public class Service<E extends ParentModel, T extends Collection<E>> { 
    private Class<T> classOfT; 
    private Class<E> classOfE; 

    public Service(Class<E> classOfE, Class<T> classOfT) { 
     this.classOfE = classOfE; 
     this.classOfT = classOfT; 
    } 
} 

public class BusinessLogic { 
    public void someLogic() { 
     Service<ChildModel, ArrayList<ChildModel>> service = new 
      Service<ChildModel, ArrayList<ChildModel>>(ChildModel.class, ArrayList.class); 
    } 
} 

Compile-time error là trong BusinessLogic::someLogic():

Các nhà xây dựng Dịch vụ < ChildModel, ArrayList < ChildModel >> (Lớp < ChildModel>, Class < ArrayList>) là undefined

Biên dịch sang Java 7.

+0

Bạn có dự định có trường 'Class' hoặc trường nào thuộc loại' T' và 'E' nào không? –

Trả lời

2

Bởi vì Generics trong Java được thực hiện "bởi erasure", không có Class<ArrayList<ChildModel>>>, chỉ có một Class<ArrayList>.

Điều bạn có thể làm là cho phép siêu kiểu.

Class<? super T> classOfT; 
Class<? super E> classOfE; 
public Service(Class<? super E> classOfE, Class<? super T> classOfT) { 

cách khác, bạn có thể double-cast lớp:

Class<ArrayList<Integer>> clazz = 
    (Class<ArrayList<Integer>>) (Class<? super ArrayList>) 
    ArrayList.class; 

Nhưng hãy cẩn thận: lớp chỉ ArrayList là - Java sẽ không thực hiện kiểm tra loại bổ sung tại thời gian chạy trên Generics. Xem cho chính bạn:

ArrayList<Integer> a1 = new ArrayList<>(); 
ArrayList<Double> a2 = new ArrayList<>(); 
System.out.println(a1.getClass() == a2.getClass()); 

Đây là cùng một lớp. Khi chạy, các generics hầu như biến mất

+0

này 'Class > clazz = (Class >) ArrayList.class;' không nên biên dịch, phải không? Tôi thích ý tưởng sử dụng 'super' mặc dù – nyname00

+0

Xin lỗi, bạn cần một diễn viên kép, với' super' hoặc 'extends'. –

1

Vì không có su ch điều như ArrayList<ChildModel>.class sẽ không có cách nào thanh lịch để giải quyết điều này. Bạn thể qua một loại nguyên liệu để bạn constructor của bạn, như đã đề cập Yassin, như thế này:

Service<ChildModel, ArrayList<ChildModel>> s1 = 
     new Service<>(ChildModel.class, (Class) ArrayList.class) 

Sự khác biệt để gọi bạn là ở đây chúng ta đang sử dụng các loại nguyên Class, trong khi ở trong ví dụ của bạn loại Class<ArrayList> được sử dụng (vì vậy đây không phải là lỗi).

Một lựa chọn khác là để có được các loại từ một ví dụ thực tế:

Class<ArrayList<ChildModel>> fromObj = 
     (Class<ArrayList<ChildModel>>) new ArrayList<ChildModel>(0).getClass(); 

Đây là tiết hơn, nhưng tôi muốn rằng trong loại thô (trong cả hai trường hợp, bạn sẽ nhận được cảnh báo trình biên dịch)

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