2014-10-08 21 views
19

Tại sao println in "tom" và không hiển thị bất kỳ ngoại lệ thời gian chạy sau khi đúc để List<Integer>, trong khi nó không có khả năng in các giá trị 1 sau khi đúc để List<String>?Generics Danh sách <String> và Danh mục <Integer> không hành xử như mong đợi

import java.util.Arrays; 
import java.util.List; 

public class Main { 
    public static void main(String args[]) { 

     List list = Arrays.asList(1, "tom"); 

     System.out.println(((List<Integer>) list).get(1)); 
     // "tom" 

     System.out.println(((List<String>) list).get(0)); 
     // ClassCastException: Integer cannot be cast to String 
    } 
} 
+5

Nó * là * hiển thị ngoại lệ thời gian chạy. – Maroun

+0

nhận xét một loại danh sách tại một thời điểm để có được kết quả mong muốn tức là // Danh sách list3 = list1; // System.out.println (list3.get (0)); – Aman

Trả lời

34

Cuộc gọi đầu tiên của println được tĩnh cử đến PrintStream.println(Object) và cuộc gọi thứ hai được cử đến PrintStream.println(String). Vì vậy, đối với cuộc gọi thứ hai trình biên dịch đặt một diễn viên tiềm ẩn để String mà sau đó thất bại với ClassCastException khi chạy.

+3

Đó là câu trả lời đúng, +1. – Maroun

+2

bạn có thể vui lòng giải thích về điều này, bcoz những gì tôi nghĩ trong trường hợp đầu tiên nó shud đi đến PrintStream.println (Integer) nếu nó đi PrintStream.println (String) cho trường hợp thứ hai hoặc cả hai shud có PrintStream.println (Object). – Aman

+7

Không có 'PrintStream.println (Integer)'. Trình biên dịch luôn gửi đến một phương thức có chữ ký cụ thể nhất. Loại cụ thể nhất cho 'Integer' là' Object', và kiểu cụ thể nhất cho 'String' là' String'. – ZhekaKozlov

0
Integer i = new Integer(101); 
String s = new String(i); // undefined and Invalid 
StringBuffer sb = new StringBuffer(i); // defined and Valid 

String s2 = "tom"; 
Integer i2 = new Integer(s2); //defined and valid 

Vì vậy, khi bạn gán một danh sách không tổng quát để một chung nó được gán nhưng khi bạn đang in nó nó kiểm tra các loại an toàn hoặc xác định nhà thầu cho đúc nếu có nhà xây dựng có giá trị và được xác định sau đó nó được in khác cho thấy lớp đúc ngoại lệ như lớp không thể được đúc do thiếu các nhà xây dựng không xác định cho đúc.

Nếu tôi sai xin vui lòng giúp tôi ra với logic đúng ...

+0

Điều này không liên quan gì đến các nhà thầu. – Radiodef

0

Đây là loại vấn đề có thể tránh được bằng cách sử dụng Generics và là động lực chính cho việc sử dụng Generics.

Đây là dòng chảy thực tế của mã của bạn, từ thứ hai println() quan điểm của bạn:

  1. mã của bạn tuyên bố một ArrayList loại Object;

  2. Nó thêm IntegerString vào ArrayList.

  3. Nó đưa danh sách của bạn vào danh sách String. Danh sách của bạn được đánh dấu là bị giới hạn ở String.

Java Generics là một tính năng thời gian biên dịch chỉ để danh sách của bạn có thể chấp nhận mà không cần bất kỳ vấn đề StringInteger yếu tố. Các đối tượng chính nó không biết gì về những gì các loại nó supossed để chứa không giống như trình biên dịch.

  1. Nó attemps để truy xuất các phần tử đầu tiên của danh sách đúc của bạn được coi là một String và đúc nó vào String ngầm.

  2. Gọi println(String x) từ PrintStream lớp học.

Nhưng yếu tố đầu tiên này thực sự không phải là String và là Integer. Bạn không thể bỏ một số Integer đến String.

Đọc Generics in Java ví dụ về phần động lực.

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