why does this compile without any unchecked type warnings?
generics, java
Solution
In both of the statements, the compiler does not have enough information to infer the type argument for `V`. When this happens, it defaults to `V`'s upper bound, which is `Object`.
The assignments are valid because both `5` and `"a string"` are assignable to `Object`.
We can show that the type of `A.create().v` is `Object` by trying to assign it to a more specific type:
Integer i = A.create().v; // Type mismatch: cannot convert from Object to Integer
The error is the same, even if we assign a more specific type first (the result of an assignment expression is the type of the assigned variable):
Integer i = (A.create().v = 5); // same error
Note that a "type witness" can be used to explicitly specify generic type arguments, in the case that they aren't inferred:
Integer i = A.<Integer>create().v; // valid
A.<String>create().v = 5; // incompatible types
A.<Integer>create().v = "a string"; //
These are contrived examples just to demonstrate compiler behavior, but a type witness is occasionally useful, for example:
static void m(List<String> list) { }
public static void main(String args[]) {
m(Collections.emptyList()); // error
m(Collections.<String>emptyList()); // valid
}
Problem
Why does the following code compile cleanly without any warnings, even with `xlint:all` ? ``` class A<V> { public V v; public <V> A() { } public static <V> A<V> create() { return new A<V>(); } } public class FooMain { public static void main(String args[]) { A.create().v = 5; A.create().v = "a string"; } } ``` running: ``` javac -Xlint:all src/FooMain.java ``` results in a clean compile without any warnings (unchecked, etc.). What is the type parametrization of the instance of the generic class `A` that gets's created on the first line and what on the second? And how does the compiler determine the type? By looking at the type of the r-values?