2008-11-24 28 views
74

Các mã saulỗi trong trình biên dịch thực hoặc trong javac ("thông số loại T không thể được xác định")

public class GenericsTest2 { 

    public static void main(String[] args) throws Exception { 
     Integer i = readObject(args[0]); 
     System.out.println(i); 
    } 

    public static <T> T readObject(String file) throws Exception { 
     return readObject(new ObjectInputStream(new FileInputStream(file))); 
     // closing the stream in finally removed to get a small example 
    } 

    @SuppressWarnings("unchecked") 
    public static <T> T readObject(ObjectInputStream stream) throws Exception { 
     return (T)stream.readObject(); 
    } 
} 

biên dịch trong nhật thực, nhưng không phải với javac (thông số loại T không thể được xác định, không có độc đáo trường hợp tối đa tồn tại cho biến kiểu T với giới hạn trên T, java.lang.Object).

Khi tôi thay đổi readObject (String file) để

@SuppressWarnings("unchecked") 
    public static <T> T readObject(String file) throws Exception { 
     return (T)readObject(new ObjectInputStream(new FileInputStream(file))); 
    } 

nó biên dịch trong nhật thực và với javac. Ai là đúng, trình biên dịch eclipse hoặc javac?

Trả lời

66

tôi muốn nói đó là lỗi trong trình biên dịch Sun báo cáo herehere, bởi vì nếu bạn thay đổi dòng của bạn vào dưới đây nó hoạt động với cả hai, mà dường như chính xác những gì được mô tả trong các báo cáo lỗi.

return GenericsTest2.<T>readObject(new ObjectInputStream(new FileInputStream(file))); 
13

Trong trường hợp này, tôi muốn nói mã của bạn sai (và trình biên dịch Sun là đúng). Không có gì trong các đối số đầu vào của bạn cho readObject để thực sự suy ra loại T. Trong trường hợp đó, bạn nên để cho nó trả về Object và cho phép các máy khách tự động bỏ kiểu kết quả.

này nên làm việc (mặc dù tôi đã không kiểm tra nó):

public static <T> T readObject(String file) throws Exception { 
    return GenericsTest2.<T>readObject(new ObjectInputStream(new FileInputStream(file))); 
} 
+1

return GenericsTest2. readObject (new ObjectInputStream (tệp FileInputStream mới); làm việc. Cảm ơn! –

+1

Tôi không đồng ý, nó trông giống như lỗi liên quan bên dưới. Trình biên dịch nên tin tưởng một diễn viên rõ ràng mà không suy luận kiểu - các biên dịch sau đây phạt tiền @SuppressWarnings ("không được kiểm tra") public static T createT (String className) ném ngoại lệ { return (T) Class.forName (className) .newInstance(); } –

3

Oracle JDK6 U22 nên đúng nhưng tôi đã vấn đề này với JDK6 U24 quá

Đây là một lỗi của nhật thực bug 98379.

này đã không được sửa nhưng vấn đề đã được giải quyết thông qua cách giải quyết như ví dụ trong lỗi eclipse (xem link)

0

Nếu bạn có thể thay đổi phương pháp readObject bạn để làm việc một cách minh bạch khi gọi, bạn cũng có thể sử dụng như sau:

public static <T> T readObject(String file, Class<T> type) throws Exception { 
    return type.cast(readObject(new ObjectInputStream(new FileInputStream(file)))); 
} 

Bằng cách này, người gọi buộc phải xác định loại kết quả và trình biên dịch biết cách truyền kết quả.

1

Tôi đã tìm thấy sự cố này trong phiên bản java "1.6.0_22". Nó biến mất khi tôi nâng cấp lên phiên bản java "1.6.0_32" vì nó đã được sửa trong bản cập nhật 25.

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