2009-09-16 32 views
18

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 SkeetAngelika 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) 
+0

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. –

+0

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? –

+1

@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

Trả lời

8

Tìm thấy những lỗi trên Sun, mà tôi nghĩ là những gì bạn 'đang mô tả:

http://bugs.sun.com/view_bug.do?bug_id=6182950
http://bugs.sun.com/view_bug.do?bug_id=6730568

+0

Lỗi này dường như được trưng bày trong Netbeans 6.9. https://netbeans.org/bugzilla/show_bug.cgi?id = 187859 –

+0

Thay đổi db77bf6adb53 (23 tháng 10 năm 2008) đối với mã OpenJDK 7 chứa sửa lỗi: http://hg.openjdk.java.net/jdk7/build/langtools/rev/db77bf6adb53. – seh

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