Gio*_*gos 0 java generics wildcard
The wildcard ? in generics represents an unknown type and accepts only null.
However, in the following example, the  constructor  accepts (for example) a String object, even though I have declared an instance of Test<?>.
public class Test<T> {
    private T object;
    public Test(T object) {
        this.object = object;
    }
    public void set(T object) {
        this.object = object;
    }
    public static void main(String[] args) {
        Test<?> test = new Test<>("Test");    // compiles fine
        //test.set("Test");    // compiler error
    }
}
Run Code Online (Sandbox Code Playgroud)
Why does this compile normally?
the constructor accepts (for example) a
Stringobject, even though I have declared an instance ofTest<?>.
No.  You have declared a variable of type Test<?>.  You have created an instance of type Test<X>, for some X that the compiler is obliged to figure out for itself such that the overall statement is valid.  That is, here:
Run Code Online (Sandbox Code Playgroud)Test<?> test = new Test<>("Test"); // compiles fine
... the <> does not mean "copy the type parameter from the type of the variable" or anything much like that. Test<?> is not the type of the expression new Test<>("Test").  That the chosen type parameter must make the type assignable to type Test<?> is one of the constraints that must be satisfied, but that's trivial, because any X will do for that.
Formally, Java will infer the most specific type parameter that satisfies all the constraints for the statement to be valid. new Test<X>("Test") is valid only for a relatively few Xs:
java.lang.Objectjava.lang.Serializablejava.lang.Comparable<String> and a few other variations on Comparablejava.lang.CharSequencejava.lang.constant.Constable (since Java 12)java.lang.constant.ConstantDesc (since Java 12)java.lang.StringString is the most specific of those, so it is the one chosen.
然而,实际上,Java 实际上根本不需要选择特定的类型参数。它只需让自己满意,至少有一个有效。
表达式test.set("Test")是不同的情况。test分配给的对象被推断为具有类型并不重要Test<String>。在这里,与在所有情况下一样,Java 根据所涉及的任何变量的声明类型来分析表达式。  test是用 type 声明的Test<?>。因此,Java 没有任何类型可以确信test.set()会接受作为参数。但是,该值null与每个引用类型兼容,因此无论对象test引用的特定类型参数是什么,null都是可接受的参数test.set()。