为什么Eclipse编译器会丢失固定类型参数?

为什么Eclipse编译器会丢失固定类型参数?,eclipse,generics,java-8,optional,type-parameter,Eclipse,Generics,Java 8,Optional,Type Parameter,我努力为这个问题找到一个合适的标题,因为我观察到的现象非常奇怪。因此,我不再逐字解释我的问题,而是向您展示一些(希望如此)自我描述的代码。考虑下面的参数化类: public class GenericOptional<T> { public GenericOptional(T someValue) {} public T getValue() { return null; } public Optional<String> getOption

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

public class GenericOptional<T> {

    public GenericOptional(T someValue) {}

    public T getValue() { return null; }

    public Optional<String> getOptionalString() { return Optional.empty(); }
}
局部变量
os
的类型为
可选
,不带类型参数
字符串
!Eclipse编译器丢失了有关固定类型参数的信息。有人知道为什么吗

现在看第二个代码示例:

public static void main(String[] args) {
    Object obj = new GenericOptional<>(Boolean.TRUE);
    GenericOptional<?> go = (GenericOptional) obj;
    Optional<String> os = go.getOptionalString();
}
publicstaticvoidmain(字符串[]args){
Object obj=新的通用选项(Boolean.TRUE);
通用选项go=(通用选项)obj;
可选os=go.getOptionalString();
}
通过将局部变量
go
声明为
genericonptional
方法
getOptionalString()
的返回类型现在是
可选的


有人能解释一下这种行为吗?

这不是关于Eclipse或其他东西,而是关于原始类型

让我们回顾一下这个片段:

public static void main(String[] args) {
    Object obj = new GenericOptional<>(Boolean.TRUE);
    GenericOptional go = (GenericOptional) obj;
    Optional os = go.getOptionalString();
}
但是,如果我们现在回顾第二个代码段

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

您正面临的行为。当您使用原始类型时,泛型实际上会完全关闭,而不管成员的泛型签名与类的类型参数之间是否存在连接

这背后的原因是,原始类型是一种只与前泛型代码向后兼容的特性。所以要么你有泛型,要么你没有

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

GenericOptional<?> go = (GenericOptional<?>) obj;
Optional<String> os = go.getOptionalString();
genericonptional go=(genericonptional)obj;
可选os=go.getOptionalString();

使用
意味着“我不知道实际的类型参数,我也不在乎,但我正在使用泛型类型检查”。

谢谢您的回答。Kocko给出了相同的答案,我不知道如何给你们两个正确/最佳的认可。因此,由于您首先回答了问题,即使您没有提供示例代码来支持您的解释,我还是会给予您“最有用”的批准。如果你认为Kocko的回答对那些想知道它是如何工作的人更有价值,请允许我说“不”,我将把“最有用的”批准转交给Kocko。谢谢Kocko的解释。请看我在霍尔格的回答中添加的评论,为什么我倾向于给他“最有帮助的”批准。希望你能接受这个决定。
public static void main(String[] args) {
    Object obj = new GenericOptional<>(Boolean.TRUE);
    GenericOptional<?> go = (GenericOptional) obj;
    Optional<String> os = go.getOptionalString();
}
public Optional<String> getOptionalString() { return Optional.empty(); }
GenericOptional<?> go = (GenericOptional<?>) obj;
Optional<String> os = go.getOptionalString();