Eclipse 编译器或 javac 中的 Bug (“ T 的类型参数无法确定”)

以下代码

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();
}
}

在 eclipse 中编译,但不能使用 javac (类型参数 T 无法确定; 类型变量 T 没有唯一的最大实例,其上限为 T,java.lang。反对)。

当我将 readObject (String file)更改为

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

它在 eclipse 中编译并且使用 javac。谁是正确的,eclipse 编译器还是 javac?

26337 次浏览

在这种情况下,我会说您的代码是错误的(Sun 编译器是正确的)。在 readObject的输入参数中没有任何实际推断 T类型的内容。在这种情况下,最好让它返回 Object,并让客户机手动强制转换结果类型。

这应该可以(尽管我还没有测试过) :

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

我认为这是 Sun 编译器报告的 给你给你中的 bug,因为如果你将你的代码行改为下面的代码行,它会同时处理这两个代码,这似乎正是 bug 报告中所描述的。

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

Oracle JDK6 u22应该是正确的,但我对 JDK6 u24也有这个问题

这是日食 窃听器98379的一个错误。

这个问题没有得到纠正,但是这个问题通过解决方案得到了解决,就像 Eclipse bug 中的例子一样(参见链接)

如果您可以在调用时修改 readObject 方法以便透明地工作,您还可以使用以下方法:

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

这样,调用方就必须指定结果的类型,而编译器知道如何强制转换结果。

我在 java 版本“1.6.0 _ 22”中发现了这个问题。当我升级到 java 版本“1.6.0 _ 32”时,它消失了,因为它在更新25中被修复了。