Tôi đã gặp vấn đề trong Generics của Java, trong đó cùng một mã sẽ biên dịch và hoạt động tốt trong Java 6, nhưng sẽ không biên dịch được vì cùng xóa trong Java 5. tôi có một TestErasure.java tập tin đó có một phương pháp quá tải, được gọi là "phương pháp":Hành vi khác biệt giữa Java 5 & 6 khi quá tải các phương thức chung
import java.util.ArrayList;
import java.util.List;
public class TestErasure {
public static Object method(List<Object> list) {
System.out.println("method(List<Object> list)");
return null;
}
public static String method(List<String> list) {
System.out.println("method(List<String> list)");
return null;
}
public static void main(String[] args) {
method(new ArrayList<Object>());
method(new ArrayList<String>());
}
}
trong Java 5, tôi nhận được lỗi biên dịch dự kiến, trong đó nêu rằng xóa các "phương pháp" là như nhau:
$ javac -version
javac 1.5.0_19
$ javac TestErasure.java
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure
public static String method(List<String> list) {
^
TestErasure.java:17: method(java.util.List<java.lang.Object>) in TestErasure cannot be applied to (java.util.ArrayList<java.lang.String>)
method(new ArrayList<String>());
^
2 errors
Tuy nhiên, Java 6 có thể biên dịch và chạy cùng mã này.
$ javac -version
javac 1.6.0_16
$ javac TestErasure.java
$ java TestErasure
method(List<Object> list)
method(List<String> list)
Dựa trên hiểu biết hiện tại của tôi về tẩy xóa (nhờ Jon Skeet và Angelika Langer), tôi thực sự mong đợi các lỗi biên dịch như ném bằng Java 5 (trừ khi một cái gì đó đã thay đổi trong cách xử lý Java Generics - mà tôi không thể tìm thấy trên ghi chú phát hành Java 6). Trong thực tế, nếu tôi thay đổi kiểu trả về của một trong những phương pháp quá tải:
public static Object method(List<Object> list) ...
public static Object method(List<String> list) ...
Java 6 cũng thất bại trong việc biên dịch vì sự tẩy xóa cùng:
$ javac TestErasure.java TestErasure.java:5: name clash: method(java.util.List<java.lang.Object>) and method(java.util.List<java.lang.String>) have the same erasure
public static Object method(List<Object> list) {
^
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure
public static Object method(List<String> list) {
^
2 errors
Có vẻ như nếu kiểu trả về trong Java 6 bằng cách nào đó ảnh hưởng đến việc lựa chọn phương pháp quá tải nào để sử dụng?
Ai đó có thể làm sáng tỏ lý do tại sao ví dụ đầu tiên hoạt động trong Java 6 - có vẻ như đi ngược lại việc xử lý các phương pháp chung đã bị quá tải đã nêu?
Thông tin thêm:
đề nghị mỗi David, ví dụ ban đầu, tuân thủ bởi javac 1.6, sẽ chạy theo java 1.5:
$ javac -target 1.5 TestErasure.java
$ java -version
java version "1.5.0_19"
$ java TestErasure
method(List<Object> list)
method(List<String> list)
The (xóa) kiểu trả về là một phần của m chữ ký ethod trong tất cả các phiên bản của Java. –
Kiểu trả về là một phần của bộ mô tả phương thức, nhưng không phải là chữ ký phương thức, đúng không? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20a%20method%20signature? –
@Tom - Tôi tin rằng bạn đã nhầm - "Định nghĩa: Hai trong số các thành phần của khai báo phương thức bao gồm chữ ký phương thức — tên của phương thức và các kiểu tham số." Từ http://java.sun.com/docs/books/tutorial/java/javaOO/methods.html. Chữ ký phương thức phải là duy nhất để quá tải phương thức hoạt động và chúng không dựa vào kiểu trả về (đối với Java, ít nhất). – weiji