2013-09-04 40 views
14

Tôi đã tìm thấy các chủ đề tương tự, nhưng quá phức tạp và không hoàn toàn giống nhau. Vì vậy, điều này là. Đây là (tối thiểu) mã đó là tốt trên 1,6, nhưng không biên dịch với 1,7 javac.JDK 1.7 phá vỡ tính tương thích ngược? (generics)

public class Test { 
    private static class A<T>{}; 
    private static class B{}; 
    private static class C{}; 

    B doSomething(A<B> arg){ 
     return new B(); 
    } 

    C doSomething(A<C> arg){ 
     return new C(); 
    } 
} 

On 1,7 lỗi là thế này:

java: name clash: doSomething(Test.A<Test.C>) and doSomething(Test.A<Test.B>) have the same erasure 

Tôi hiểu các loại tẩy xoá và tại sao nó là một sai mã. Tôi chỉ không hiểu tại sao chúng ta có thể có mã này trong dự án của chúng tôi biên dịch và chạy trong 1.6, khi 1.7 có vấn đề với nó. Chuyện gì thế? Nó là một lỗi trong trình biên dịch 1,6 mà nó cho phép chúng ta làm như vậy? Có thể làm cho nó hoạt động trong 1,7 trừ viết lại không?

  • phiên bản JDK1.6 javac: 1.6.0_43
  • phiên bản JDK1.7 javac: 1.7.0_25

Trả lời

13

Bạn đang hoàn toàn đúng, dưới JLS3 mã này nên không bao giờ tôi đã biên soạn và đây là một lỗi trong 1.6.

Để giải phóng 1,7 phần lớn hệ thống kiểu cơ bản đã được cập nhật và lỗi này đã được sửa, kết quả là xử lý loại tốt hơn với chi phí của một số vấn đề tương thích ngược.

Để làm cho nó hoạt động ở mức 1.7, tôi tin rằng việc tái thanh toán là lựa chọn duy nhất của bạn.

+1

Cám ơn lời giải thích . Nhưng tôi vẫn không thích rằng họ đã phá vỡ khả năng tương thích ngược. – NeplatnyUdaj

+1

@NeplatnyUdaj: Sửa lỗi không phá vỡ tính tương thích ngược. – newacct

+1

@newacct: Tôi nghĩ rằng đó là, bởi vì rất nhiều mã có thể phụ thuộc vào nó. Bạn có biết một nhà phát triển đã đọc toàn bộ JLS không? – NeplatnyUdaj

6

Đây là một trong các lỗi trong javac đã được sửa trong Java 7 - bạn có thể tìm thêm thông tin trong release notes. Tôi sợ lựa chọn duy nhất của bạn là phải viết lại mã nếu bạn muốn chuyển sang Java 7.

Diện tích: Tools
Tóm tắt: Một lớp không thể xác định hai phương pháp với Chữ ký bị xóa Cùng nhưng Hai loại trả lại khác nhau
Mô tả: Lớp không thể xác định hai phương thức có cùng chữ ký bị xóa, bất kể kiểu trả về có giống nhau hay không. Điều này sau từ JLS, Java SE 7 Edition, phần 8.4.8.3. Trình biên dịch JDK 6 cho phép các phương thức có cùng chữ ký bị xóa nhưng các kiểu trả về khác nhau; hành vi này là không chính xác và đã được cố định trong JDK 7.
Ví dụ:

class A { 
    int m(List<String> ls) { return 0; } 
    long m(List<Integer> ls) { return 1; } 
} 

Mã này biên dịch dưới JDK 5.0 và JDK 6, và bị từ chối theo JDK 7.

+0

Chính xác hành vi của 'A' trong' Java 5' và 'Java 6' là gì?Nó có thực sự chọn cái thích hợp hay chỉ là chọn cái đầu tiên (hoặc cuối cùng)? Còn nếu bạn cố gắng gọi nó bằng, hãy nói, 'Danh sách '? – Kevin

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