The following program compiles in Java 7 and in Eclipse Mars RC2 for Java 8:
import java.util.List;
public class Test {
static final void a(Class
Disclaimer - I don't know enough about the subject, and the following is an informal reasoning of mine to try to justify javac's behavior.
We can reduce the problem to
> void a(Class type) throws Exception
{
X instance = type.newInstance();
b(instance); // error
}
List b(List list) { ... }
To infer T
, we have constraints
X <: List>
X <: List
Essentially, this is unsolvable. For example, no T
exists if X=List>
.
Not sure how Java7 infers this case. But javac8 (and IntelliJ) behaves "reasonably", I'd say.
Now, how come this workaround works?
List> instance = type.newInstance();
b(instance); // ok!
It works due to wildcard capture, which introduces more type info, "narrowing" the type of instance
instance is List> => exist W, where instance is List => T=W
Unfortunately, this is not done when instance
is X
, thus there is less type info to work with.
Conceivably, the language could be "improved" to do wildcard capture for X too:
instance is X, X is List> => exist W, where instance is List