In Java, Generics1,2,3 uses type parameters. The code in your question uses type arguments and not type parameters. Similar to method parameters vs method arguments as explained in Difference between arguments and parameters in Java.
Even if you replace the String
with the ?
wildcard, the code still compiles, i.e.
WeakReference<?> ps = new WeakReference<>(new String());
if (ps instanceof WeakReference<?>) {
System.out.println("Ok");
}
This is because the same generic argument is being used, i.e. ?
If you replace the arguments with parameters, then the code will not compile, for example:
import java.lang.ref.WeakReference;
public class TestClaz<T> {
public static <T> void main(String[] args) {
WeakReference<T> ps = new WeakReference<>(new String());
if (ps instanceof WeakReference<T>) {
System.out.println("Ok");
}
}
}
Here T
is a type parameter (and not a type argument) and my IDE4 gives the following compiler error:
Cannot infer type arguments for WeakReference<>
This part of the code does not compile:
WeakReference<T> ps = new WeakReference<>(new String());
If I change that line to:
WeakReference<T> ps = new WeakReference<T>(new String());
Then the compiler error becomes:
The constructor WeakReference<T>(String) is undefined
Now I can add a cast to T
, as in:
WeakReference<T> ps = new WeakReference<T>((T) new String());
and then the code compiles but with the following [compiler] warning:
Unchecked cast from String to T
In other words, the compiler cannot know whether String
can be cast to T
because, at runtime, T
could be any class and not necessarily one that can be cast to String
, hence the compiler cannot verify that String
can be cast to T
.
1 Generics lesson in Oracle's Java tutorials.
2 Generics bonus lesson in Oracle's Java tutorials.
3 Generics guide from Oracle's Java documentation.
4 My IDE is Eclipse.