为什么这个 Java 代码能编译通过?

4

为什么这个可以编译通过?

A中使用了没有任何泛型参数的B,在Java中也能够编译通过。这是怎么回事呢?

interface B<T>
{
    public T Foo(T value);
}

public class A
{
    public B What()
    {
        return null;
    }

    public void Foo()
    {
        B x = What();
        x.Foo(123);
    }
}
2个回答

9

这是为了与早期版本的J2SE 5.0 Java兼容而设置的。您应该会收到一个rawtypes警告(请注意编译器警告)。


1
如果编译成本地代码,那么一切都是编译器虚构。 - Tom Hawtin - tackline
@SteveP。它之所以有效,是因为该语言是按此设计的,并且编译器遵循规范。擦除是1.5全类型系统到1.5前子集之间的映射。该映射在语言中以各种方式使用(并非所有都与运行时类型有关!)。 - Tom Hawtin - tackline
@TomHawtin-tackline - 不,JVM执行大多数类型检查,但对泛型一无所知。与内部类类似。 - Hot Licks
@HotLicks JVM(Java虚拟机)基本上是无关紧要的,除了对Java语言施加奇怪的扭曲之外。 - Tom Hawtin - tackline
@TomHawtin-tackline - 有人可能会将这个论点颠倒过来。javac和一些被添加到其中的垃圾强制JVM通过奇怪的扭曲。 - Hot Licks

7
在这里,您只是使用了B的一个raw类型。就像...
 List list = new ArrayList(); // defined as: public interface List<E>

这是完全有效的,但不建议使用。


list 可以添加什么类型的对象?所有东西都被视为 Object 吗? - Reactgular
使用原始类型意味着可以向其中添加任何对象。因此,如果您有一个没有泛型的“String”列表,编译器在之后尝试将“Integer”添加到其中时不会抱怨。 - Ravi K Thapliyal
2
@nachokk 不一样,编译器会稍微以不同的方式处理原始类型的表达式。(但可能已经足够接近了。) - millimoose
@nachokk:这不一样。你可以将List<String>分配给List,但不能将List<String>分配给List<Object> - newacct

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接