JDK-8162708 : Unexpected syntax error with ternary operator and generics methods
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86_64
  • Submitted: 2016-07-28
  • Updated: 2016-07-28
  • Resolved: 2016-07-28
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-1~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u3 (2016-07-02) x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
If you have a method in a generic class declared as follow:

class Foo<T> {
  public T getValue() {
    // returns a value ...
  }
}

and you call the method above inside a ternary operator as follow

Foo<Integer> foo = new Foo<>();
Float f = new Random().nextBoolean() ? foo.getValue() : 0f;

you get a syntax error from the javac 1.8 compiler. 

But the code above compiles with no errors and warnings with both javac 1.7 and 1.9.

I wonder which behavior is correct according to JLS: is this a javac 1.8 bug or the 1.8 behavior is the only right one?

REGRESSION.  Last worked in version 7u80

ADDITIONAL REGRESSION INFORMATION: 
It works both in previous major release 1.7 and next major release 1.9
I tried with javac 1.7.0_101 and javac 9-ea and with both compiles with no errors or warnings.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the class TernaryOperatorBug (submitted in the source code section) with the command 

javac -Xdiags:verbose TernaryOperatorBug.java 

using the version 1.8.0_91



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The class compiled without errors or warnings.
ACTUAL -
I get the syntax error below:

$ javac -Xdiags:verbose TernaryOperatorBug.java
TernaryOperatorBug.java:15: error: incompatible types: bad type in conditional expression
                f = random.nextBoolean() ? me.justReturn(random.nextInt()) : new Float(random.nextFloat());
                                                        ^
    Integer cannot be converted to Float
1 error



REPRODUCIBILITY :
This bug can be reproduced always.

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

public class TernaryOperatorBug<I>
{
	public static void main(String[] args)
	{
		TernaryOperatorBug<Integer> me = new TernaryOperatorBug<>();
		Random random = new Random(System.nanoTime());
		
		// Compiles with no errors of warnings
		Float f = random.nextBoolean() ? new Integer(random.nextInt()) : new Float(random.nextFloat());
		me.print(f);

		// Syntax error with javac 1.8!
		f = random.nextBoolean() ? me.justReturn(random.nextInt()) : new Float(random.nextFloat());
		me.print(f);
	}
	
	public I justReturn(I value)
	{
		return value;
	}
	
	public void print(Object value)
	{
		System.out.println(value);
	}
	
}

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

CUSTOMER SUBMITTED WORKAROUND :
The workaround is to compile with java 1.7 or 1.9. The Eclipse ECJ compiler works fine, also.


Comments
This issue is only applicable to 8u, there is no issue in 7 and 9 8uxx - Fail (including 8u102) 7uxx - Pass 9 ea b-127 - Pass below is the result == 9 ea b-127 == -sh-4.1$ /opt/java/jdk-9_ea-127/bin/javac -Xlint TernaryOperatorBug.java TernaryOperatorBug.java:11: warning: [deprecation] Integer(int) in Integer has been deprecated Float f = random.nextBoolean() ? new Integer(random.nextInt()) : new Float(random.nextFloat()); ^ TernaryOperatorBug.java:11: warning: [deprecation] Float(float) in Float has been deprecated Float f = random.nextBoolean() ? new Integer(random.nextInt()) : new Float(random.nextFloat()); ^ TernaryOperatorBug.java:15: warning: [deprecation] Float(float) in Float has been deprecated f = random.nextBoolean() ? me.justReturn(random.nextInt()) : new Float(random.nextFloat()); ^ 3 warnings == 7uxx == -sh-4.1$ /opt/java/jdk1.7.0_80/bin/javac TernaryOperatorBug.java == 8uxx == -sh-4.1$ /opt/java/jdk1.8.0/bin/javac TernaryOperatorBug.java TernaryOperatorBug.java:15: error: incompatible types: bad type in conditional expression f = random.nextBoolean() ? me.justReturn(random.nextInt()) : new Float(random.nextFloat()); ^ Integer cannot be converted to Float 1 error ==
28-07-2016