2016-08-10 17 views
12

Tôi đã thử tay trên vectơ và viết một mã đơn giản để truy cập các phần tử của nó thông qua liệt kê.Tôi nhận ngoại lệ ClassCast khi tôi liệt kê vectơ với tham số kiểu chuỗi, nhưng không có ngoại lệ nào với Integer là tham số kiểu

Vector v = new Vector(); 
    v.add("Some String"); 
    v.add(10); 

    Enumeration e = v.elements(); 
    while(e.hasMoreElements()) System.out.println(e.nextElement()); 

Làm việc với các loại thô tạo ra kết quả như mong đợi (in các phần tử). Nhưng, khi tôi sử dụng kiểu tổng hợp của điều tra viên, nó trở nên phức tạp.

Với String như kiểu tham số:

Vector v = new Vector(); 
    v.add("Some String"); 
    v.add(10); 

    Enumeration<String> e = v.elements(); 
    while(e.hasMoreElements()) System.out.println(e.nextElement()); 

Output:

Một số chuỗi

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer không thể là truyền đến java.lang.String

Với số nguyên là loại tham số:

Vector v = new Vector(); 
    v.add("Some String"); 
    v.add(10); 

    Enumeration<Integer> e = v.elements(); 
    while(e.hasMoreElements()) System.out.println(e.nextElement()); 

Output:

Một số chuỗi

gì đang xảy ra ở đây? Không phải cả hai trường hợp đều có ngoại lệ ClassCast?

+1

'Liệt kê <> e = v.elements();' Biên dịch này như thế nào? –

+0

@KonstantinYovkov Tôi nghĩ đó là lỗi đánh máy và OP có nghĩa là 'Liệt kê '. – Mena

+0

Bạn đang sử dụng loại nguyên mẫu 'Vector': http://stackoverflow.com/a/2770692/1608594 Bạn không nên sử dụng các loại thô. – carbolymer

Trả lời

5

Lưu ý rằng tất cả các generics đều bị xóa khi biên dịch, nó chỉ giúp trình biên dịch xác nhận bạn đã không mắc lỗi. Có lẽ bạn nhận được một số cảnh báo tại thời điểm này, nói rằng bạn không nên sử dụng các loại thô (phương tiện thô Vector thay vì Vector<String> v.v.). Các generics tương đương với một loại thô là <?> cho biết bạn sẽ cho phép bất kỳ loại nào (lưu ý rằng điều đó sẽ khiến bạn không mã hóa trình biên dịch nữa).

Các hành vi bạn thấy là do có hai (trên thực tế nhiều hơn, nhưng trong trường hợp của bạn hai được sử dụng) chức năng với tên System.out.println() và các loại thông số khác nhau, điều này được gọi là (phương pháp quá tải):

  1. System.out.println (string)
  2. System.out.println (Object)

Tại thời gian biên dịch nó được quyết định đó được gọi là cho mã của bạn.

Trong ví dụ về chuỗi, kiểu liệt kê có loại chung String và sẽ gọi đầu tiên. Tuy nhiên, khi nó được chuyển một đối tượng Integer từ Vector của bạn, điều này gây ra lỗi khi truyền tới String. Vì vậy, trong trường hợp này, trình biên dịch chuyển mã của bạn vào những điều sau đây (xấp xỉ):

Enumeration e = v.elements(); 
while(e.hasMoreElements()) System.out.println((String)e.nextElement()); 

Trong ví dụ Integer kiểu liệt kê đã generic loại Integer mà sẽ lập bản đồ để System.out.println(Object), mà chấp nhận cả StringInteger, vì vậy tất cả suôn sẻ.

Trên sidenote: theo mặc định, bạn nên sử dụng ArrayList thay vì Vector, nó có giao diện sạch hơn nhiều, do phương pháp kế thừa trong Vector. Ngoài ra Vector nó được đồng bộ hóa gây ra chi phí không cần thiết.

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