2013-07-31 36 views
6

Tại sao điều này xảy ra? Một dòng trong mã hoạt động tốt trong khi dòng tương tự khác thì không. Loại diễn xuất tự động chỉ xảy ra trong một số điều kiện nhất định? Tôi đã cố gắng gán gt.echoV() cho một đối tượng và nó hoạt động tốt; nhưng khi tôi gán nó cho một String, lỗi tương tự sẽ xuất hiện trở lại.Loại phương pháp chung Java đúc

public class GeneMethodTest { 

    public static void main(String... args) { 
     GeneMethodTest gt = new GeneMethodTest(); 
     gt.<String>echoV(); //this line works well 
     gt.<String>echoV().getClass();//this line leads to a type cast exception               
    } 

    public <T> T echoV() { 
     T t=(T)(new Object());                  
     return t; 
    } 
} 
+1

Câu trả lời này có thể giúp http://stackoverflow.com/a/3437930/1316346 –

+0

'(T) (đối tượng mới())' là một * bỏ chọn * - đảm bảo đọc trên đó là gì và các tác động, cùng với * loại tẩy xóa *. –

+0

Yup, tôi biết điều đó. @PaulBellora Trên thực tế (T) (đối tượng mới()) sẽ không làm gì trong thời gian chạy vì loại xóa. Vấn đề là khi tôi gọi gt. .echoV() việc đúc lớp tự động không có hiệu lực trong khi nó có hiệu ứng khi tôi gọi gt. echo.getClass() –

Trả lời

4

gt.<String>echoV().getClass(); sản xuất tương đương với trình tự sau đây hoạt động:

// Inside echoV 
Object t = new Object(); // Note that this is NOT a String! 
Object returnValue = t; 
// In main 
String stackTemp = (String) returnValue; // This is the operation that fails 
stackTemp.getClass(); 

gì bạn nhận được "miễn phí" với Generics là (String) đúc. Không có gì khác.

+0

Đúng vậy. Dường như trình biên dịch sẽ tìm ra khi nào để chèn mã thay vì chèn nó mỗi lần ~ –

+0

@charles_ma - Yep, lấy đi getClass và các số liệu trình biên dịch không cần thiết cho dàn diễn viên. –

2

này hoạt động hoàn hảo, không có gì đặc biệt, sử dụng bình thường của Generics

gt.<String>echoV(); //this line works well 

Ở đây chúng ta có một cái gì đó ít rõ ràng. Bởi vì phương pháp chung được quy định tại thời gian chạy không JVM không biết loại của lớp phương pháp chung sẽ trở lại tại compiletime, vì thế mà classTypeException

gt.<String>echoV().getClass();//this line leads to a type cast exception 

bạn nên phân bổ nó vào một biến đầu tiên, bởi vì JVM không biết loại của biến tại compiletime

String s = gt.<String>echoV(); 
s.getClass(); 
+2

Thực ra nếu bạn thực hiện 'System.out.println (gt. echoV())' bạn có 'java.lang.ClassCastException'. –

+0

cùng một vấn đề, System.out.println dự kiến ​​một chuỗi là tham số. Nếu đây không phải là trường hợp, nó sẽ gọi toString() của đối tượng, nhưng tại compileat hiện jvm không biết từ những gì đối tượng –

+0

Tôi tin rằng có lẽ đó là bởi vì trong dòng đầu tiên, tôi gọi là chức năng nhưng không sử dụng tham chiếu để trình biên dịch không bận tâm thêm bất kỳ mã lớp nào; nhưng trong dòng thứ hai, tôi đã cố gắng sử dụng tham chiếu kết quả từ cuộc gọi để trình biên dịch đã chèn mã lớp lớp học ở đó ~ Và tình huống tương tự khi bạn gọi System.out.println (gt. echoV()) @ System.exit –

1

thay đổi dòng này:

gt.<String>echoV().getClass(); 

tới:

(gt.echoV()).getClass(); 

và nó sẽ biên dịch
(nó sẽ trở lại: lớp java.lang.Object)

Gốc của ClassCastException là phương thức trả về t (của chung loại T đó là một đối tượng) và bạn cố gắng để downcast nó thành một String. Bạn cũng có thể thay đổi mã của mình để trả lại:

return (T)"some-string"; 

để xóa lỗi.

Chung được trình biên dịch sử dụng để kiểm tra loại đối tượng mong đợi, do đó, nó có thể phát hiện sai sót của nhà phát triển trong thời gian biên dịch (so với lỗi thời gian chạy). Vì vậy, IMHO theo cách này sử dụng generics nhịp đập mục đích.

+0

downvoter - chăm sóc để viết bình luận? tôi đã viết gì đó không chính xác? – alfasin

+1

Tôi nghĩ rằng câu hỏi là về việc sử dụng Generics, không phải là phương thức chính của ´getClass() ´. –

+1

@ System.exit Tôi nghĩ rằng câu trả lời của tôi cũng đề cập đến điều đó. – alfasin

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