2013-08-29 47 views
5

Tôi đã tự hỏi tại sao nó không thể gọi List<Number> không phải với List<Integer> thậm chí Integer là một lớp mở rộng của số lớp trừu tượng? Có một lỗi logic như tôi có thể gọi một phương pháp với số tham số cũng với số nguyên.Tại sao không thể gọi Danh sách <Number> không có trong Danh sách <Integer> ngay cả khi Số nguyên mở rộng Số?

public class Que 
{ 

public void enterNumbers(List<Number> nummern) 
{ 
    for (Number number : nummern) 
    { 
     System.out.println(number + "\n"); 
    } 
} 

public void enterNum(Number num) 
{ 
    System.out.println("This is a number " + num); 
} 

public static void main(String[] args) 
{ 
    Que que = new Que(); 

    Integer myInteger = new Integer(7); 
    // possible (of course!) 
    que.enterNum(myInteger); 

    List<Integer> num = new ArrayList<Integer>(); 
    num.add(4); 
    num.add(45); 
    Integer inte = new Integer(333); 

    num.add(inte); 
    // not possible ! 
    que.enterNumbers(num); 
} 
} 

Để giải quyết nó tôi có thể làm việc với List<?> hoặc List<? extends Number> ... vì vậy tôi không cần các giải pháp tôi muốn biết lý do chính xác.

Giải pháp duy nhất tôi có thể nghĩ về Danh sách được liên kết với Số làm Loại cấu trúc dữ liệu mới.

+1

http://docs.oracle.com/javase/tutorial/java/generics/inheritance.html – kosa

+3

Hãy suy nghĩ về nó: 'Danh sách 'bạn có thể thêm một' Double'. 'List ' bạn không thể thêm 'Double'. –

+5

Bởi vì generics không phải là biến thể giống như mảng. Xem [** câu hỏi này **] (http://stackoverflow.com/q/17384083/1348195) để biết thêm chi tiết. –

Trả lời

11

Vì bạn có thể, ví dụ: thêm một thể hiện của một lớp con khác nhau của Number-List<Number>, ví dụ, một đối tượng kiểu Double, nhưng rõ ràng là bạn không được phép để thêm chúng vào List<Integer>:

public void myMethod(List<Number> list) { 
    list.add(new Double(5.5)); 
} 

Nếu bạn được phép gọi myMethod với một thể hiện của List<Integer> điều này sẽ dẫn đến xung đột khi add được gọi.

+0

đó là một lời giải thích tốt ... có ý nghĩa! – Fendrix

+1

upvote để được nhanh hơn và chính xác :) –

8

Generics không đồng biến như mảng. Điều này không được phép vì loại xóa.

Xem xét các lớp học Vehicle, BikeCar.

Nếu bạn thực hiện

public void addVehicle(List<Vehicle> vehicles){ 
    vehicles.add(new Car()); 
} 
  • này là có thể, bởi vì một Car là loại Vehicle, bạn có thể thêm một Car vào Vehicle vì nó đi IS-Một thử nghiệm.
  • Nhưng điều gì sẽ xảy ra nếu được phép vượt qua List<Bike> đến addVehicle(List<Vehicle> vehicles)?

bạn sẽ thêm Car vào danh sách xe đạp. đó là đồng bằng sai. Vì vậy, generics không cho phép điều này.

Đọc về Polymorphism with generics