What does Java's type parameter wildcard really mean? What's the real difference between Foo and Foo<?>?

后端 未结 5 999
清酒与你
清酒与你 2021-01-05 02:32

For a generic interface:

public interface Foo {
    void f(T t); 
} 

The difference between the two fields:

publ         


        
5条回答
  •  一向
    一向 (楼主)
    2021-01-05 03:05

    Foo is semantically the same as Foo: it is a Foo with type parameter of something specific, but the only thing known about "something" is that it is some subclass of Object (which isn't saying too much, since all classes are subclasses of Object). Foo, on the other hand, is a Foo with type parameter specifically Object. While everything is assignment-compatible with Object, not everything will be assignment-compatible with ? where ? extends Object.

    Here's an example of why Foo should generate an error:

    public class StringFoo implements Foo {
        void foo(String t) { . . . }
    }
    

    Now change your example to this:

    Foo foo1 = new StringFoo();
    

    Since i is an Integer, there's no way that the compiler should allow foo1.foo(i) to compile.

    Note that

    Foo foo4 = new StringFoo();
    
    
    

    will also not compile according to the rules for matching parameterized types since Object and String are provably distinct types.

    Foo (without type parameter at all—a raw type) should usually be considered a programming error. According to the Java Language Specification (§4.8), however, the compiler accepts such code in order to not break non-generic, legacy code.

    Because of type erasure, none of this makes any difference to generated the byte code. That is, the only differences between these are at compile time.

    提交回复
    热议问题