gpt4 book ai didi

java - 使用具有多个边界的泛型时,编译器不会打印编译时错误

转载 作者:行者123 更新时间:2023-12-02 10:43:00 25 4
gpt4 key购买 nike

我试图理解为什么编译器不会在下面的代码中打印编译时错误。它编译,但显然不会工作。

有人知道为什么编译器允许它吗?

public class Tests {
public static void main(String... args){
// Lines below are acceptable for the compiler and work well in runtime.
GenericClass<FooClassWithFooInterface> genericClass1 = new GenericClass();
genericClass1.print(new FooClassWithFooInterface());

// Lines below are oddly acceptable for the compiler and, obviously, won't work in runtime.
GenericClass genericClass2 = new GenericClass();
genericClass2.print(new FooClassWithFooInterface());
genericClass2.print(new FooClass()); // why the compiler not throw a compile-time error?
}
}


class GenericClass<T extends FooClass & FooInterface>{
public void print(T t){
t.fooMethod();
}
}

class FooClass{

}

interface FooInterface{
public void fooMethod();
}

class FooClassWithFooInterface extends FooClass implements FooInterface{
@Override
public void fooMethod() {
System.out.println("foo");
}
}

控制台输出:
foo
foo
Exception in thread "main" java.lang.ClassCastException: FooClass cannot be cast to FooInterface
at GenericClass.print(Tests.java:18)
at Tests.main(Tests.java:11)

我创建 fooMethod() 只是为了强制执行此运行时错误。

我认为编译器可以检查 new FooClass()<? extends FooClass & FooInterface> 不匹配并强制编译时错误。

如果我们将 GenericClass 更改为 T extends FooClassWithFooInterface , 而不是 T extends FooClass & FooInterface ,编译器最终显示编译时错误:
class GenericClass<T extends FooClassWithFooInterface>{
public void print(T t){
t.fooMethod();
}
}

此外,我在 Restrictions on Generics(The Java Tutorial) 中没有发现与此问题相关的任何限制。

最佳答案

当您使用多个边界时,在编译时类型删除之后,第一个边界将保留在类型签名中。根据需要插入强制转换以用于后续边界。因此,如果您要查看已编译的 GenericClass ,你会看到类似

class GenericClass {
public void print(FooClass t){
((FooInterface) t).fooMethod();
}
}

因为编译器看到 GenericClass有一个 print(FooClass)方法,它不会提示。但是在运行时,方法内部的强制转换失败。

为什么编译器允许这样做,当人类可以推断这必然会失败时?好吧,编译器没有你那么聪明。只有当您将自己限制为类型安全代码时,它才能发现问题,这意味着永远不要使用原始类型或禁止类型警告。

还有其他几种情况,一个人在查看上下文时可以推断其他操作是安全的,但编译器会提示。编译器只使用声明的信息,一次只查看一个表达式;它不考虑泛型类型的整个上下文。

关于java - 使用具有多个边界的泛型时,编译器不会打印编译时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29568058/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com