JDK-6721146 : type-inference from return-type not applied in conditional expressions
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2008-07-01
  • Updated: 2011-10-31
  • Resolved: 2008-07-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7Resolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
The following program doesn't compile:

import java.util.*;

public class TestGenerics {
    List<String> test1(boolean b) {        
            return b ? Collections.emptyList()  : Collections.emptyList();
    }

    List<String> test2(boolean b) {        
            if (b) 
                return Collections.emptyList();
             else
                return Collections.emptyList();
    }
}

More precisely, method test2() compiles without problem, while test1() doesn't. I think that this is the expected behaviour as it is a result of  JLS 15.25 (conditional expression) and 15.12.2.8 (Inferring unconstrained type-variables). In particular, it does not seem that a ternary operator consitute an assignment context - this makes type-inference infer T=Object, thus making the RHS (List<Object> incompatible with the LHS (List<String>).

Would it be possible to extend the JLS so to make type-inference succeed in such a setting?

Comments
EVALUATION As noted in the evaluation of 6721089, the assignment conversion context needed to infer the type of emptyList only exists when an assignment operator is present. Strictly speaking, the return statements in test2 have no authority to consider themselves in an assignment conversion context or to use test2's return type to infer the type of emptyList. The ternary operator is playing dumb, but it's playing by the rules. The general problem is quite hard - what if test1/test2 was generic and its return type used a type argument inferred from the calling context of test1/test? Odersky has studied this and we may solve the problem in a limited way (but including for simple contexts like in this CR) in JDK7.
24-07-2008