我很难为这个问题找到一个合适的标题,因为我观察到的现象非常奇怪。因此,我跳过字面解释我的问题,而是向您展示一些(希望如此)自描述代码。考虑以下参数化类:
public class GenericOptional<T> {
public GenericOptional(T someValue) {}
public T getValue() { return null; }
public Optional<String> getOptionalString() { return Optional.empty(); }
}
我想强调的是返回类型Optional<String>
方法的getOptionalString()
不依赖于类型参数 T
.
现在看一下以下代码,它是使用 Java 8u45 在 Eclipse Luna 4.4.2 中编译的:
public static void main(String[] args) {
Object obj = new GenericOptional<>(Boolean.TRUE);
GenericOptional go = (GenericOptional) obj;
Optional os = go.getOptionalString();
}
局部变量os
类型为 Optional
没有类型参数 String
! Eclipse 编译器丢失了有关固定类型参数的信息。有谁知道为什么吗?
现在看第二个代码示例:
public static void main(String[] args) {
Object obj = new GenericOptional<>(Boolean.TRUE);
GenericOptional<?> go = (GenericOptional) obj;
Optional<String> os = go.getOptionalString();
}
通过声明局部变量go
如GenericOptional<?>
方法的返回类型getOptionalString()
现在是Optional<String>
正如预期的那样。
有人可以解释一下这种行为吗?
最佳答案
您面临raw types的行为。当您使用原始类型时,无论成员的泛型签名和类的类型参数之间是否存在联系,泛型都会被有效地完全关闭。
其背后的原因是原始类型只是向后兼容前泛型代码的功能。所以你要么有泛型,要么没有。
如果泛型方法不依赖于类的实际类型参数,问题很容易修复:
GenericOptional<?> go = (GenericOptional<?>) obj;
Optional<String> os = go.getOptionalString();
使用<?>
意味着“我不知道实际的类型参数,我不在乎,但我正在使用通用类型检查”。
关于eclipse - 为什么 Eclipse 编译器会丢失固定类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31019723/