为什么Eclipse Compiler会丢失固定类型参数?

Har*_*ezz 6 eclipse generics optional type-parameter java-8

我努力为这个问题找到一个合适的头衔,因为我观察到的现象非常奇怪.因此,我逐字逐句解释我的问题,而是向您展示一些(希望)自我描述的代码.考虑以下参数化类:

public class GenericOptional<T> {

    public GenericOptional(T someValue) {}

    public T getValue() { return null; }

    public Optional<String> getOptionalString() { return Optional.empty(); }
}
Run Code Online (Sandbox Code Playgroud)

我想强调的是,返回类型Optional<String>的方法,getOptionalString()不依赖于类型参数 T.

现在看看下面的代码,它使用Java 8u45Eclipse Luna 4.4.2中编译:

public static void main(String[] args) {
    Object obj = new GenericOptional<>(Boolean.TRUE);
    GenericOptional go = (GenericOptional) obj;
    Optional os = go.getOptionalString();
}
Run Code Online (Sandbox Code Playgroud)

局部变量os的类型Optional没有type-parameter String!在Eclipse的编译器已经失去了对固定的信息类型参数.有谁知道为什么?

现在看第二个代码示例:

public static void main(String[] args) {
    Object obj = new GenericOptional<>(Boolean.TRUE);
    GenericOptional<?> go = (GenericOptional) obj;
    Optional<String> os = go.getOptionalString();
}
Run Code Online (Sandbox Code Playgroud)

通过声明局部变量go作为方法GenericOptional<?>的返回类型getOptionalString()现在是Optional<String>预期的.

愿有人解释这种行为吗?

Hol*_*ger 4

您面临着原始类型的行为。当您使用原始类型时,无论成员的泛型签名和类的类型参数之间是否存在联系,泛型实际上都被完全关闭。

\n\n

其背后的原因是原始类型是仅向后兼容泛型之前的代码的功能。所以要么你有泛型,要么你的don\xe2\x80\x99t。

\n\n

如果泛型方法不依赖于类的实际类型参数,问题很容易解决:

\n\n
GenericOptional<?> go = (GenericOptional<?>) obj;\nOptional<String> os = go.getOptionalString();\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用<?>意味着 \xe2\x80\x9c我不知道\xe2\x80\x99t 实际类型参数,我不关心\xe2\x80\x99,但我\xe2\x80\x99m 使用通用类型检查\xe2\x80\x9d。

\n