JDK-6220689 : Type arguments for a class shall be inferred on constructor invocation
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_9
  • CPU: sparc
  • Submitted: 2005-01-24
  • Updated: 2010-04-04
  • Resolved: 2006-12-08
Related Reports
Relates :  
Relates :  
Relates :  
Consider the following piece of code:

List<Map<String,List<Integer>>> list = new ArrayList<Map<String,List<Integer>>>();

One has to repeat type parameters twice (and they can be even longer
than in this example). This kind of repetition of type arguments is
bug-prone and creates unnecessary clutter in the code. One shall be
able to write this code simpler, like this:

List<Map<String,List<Integer>>> list = new ArrayList();

For ease of development.

The proposed code shall compile normally via type parameter inference mechanism.

This code complies, but produces unchecked warnings.

---------- BEGIN SOURCE ----------
import java.util.*;

public class ListCreate {
	public static void main(String[] args) {
		List<Map<String,List<Integer>>> list = new ArrayList();

---------- END SOURCE ----------

Use static factory methods instead of constructors. They work just
fine with type argument inference without any warnings.

import java.util.*;

public class ListCreate2 {
        public static void main(String[] args) {
                List<Map<String,List<Integer>>> list = newArrayList();

        public static <T> ArrayList<T> newArrayList() {
                return new ArrayList<T>();
###@###.### 2005-1-24 13:16:39 GMT

EVALUATION A nominal system where aliases are declared explicitly (and can even be suggested by your IDE) is much better for readability than an inference system. When inference cannot unify explicit type arguments on the LHS with implicit type parameters on the RHS, the errors alone will be incomprehensible. (This is alluded to in the 6242254 Evaluation.) Moreover, if you allow List<Map<String,List<Integer>>> list = new ArrayList(); // (1) then you have to allow List<Map<String,List<Integer>>> list = m(); // (2) ArrayList m() { return new ArrayList(); } or even void n(List<Map<String,List<Integer>>> x) {...} n(m()); // (3) It's one thing to do inference at a 'new' statement like (1), but to do it at arbitrary method calls like (2) and (3) would imply target typing everywhere. This is definitely not going to happen.

EVALUATION If the designer of a class can control when inference is used, perhaps it would be less problematic. We could enhance generic constructors so that the type variable can be used to specify the type of the new instance, for example: class Foo<T> { <S> Foo<S>() {} } The second <S> is the "enhancement". See http://forum.java.sun.com/thread.jspa?threadID=668411

EVALUATION Inference of actual type arguments of generic types is not going to happen. See bug 6242254 for discussion. What might help in this case is type aliasing, which would likely be done through extending import clauses. There are separate bugs for that as well. ###@###.### 2005-04-26 18:26:24 GMT