JDK-8038983 : Postfix increment operator within lambda is not evaluated as expected
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2014-03-26
  • Updated: 2014-04-06
  • Resolved: 2014-04-06
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
When a postfix increment expression appears within the body of a lambda, it evaluates in the same way as a prefix increment expression. 

Take for example


The output of this program is:

anonymous class returns: 0
lambda returns: 1

where you would expect it to return 0 in both cases.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the code provided below. Inspect the output.




EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We would expect the following output

anonymous class returns: 0
lambda returns: 0

since 

t -> t++;

should be equivalent to

t -> {return t++;};


ACTUAL -
The following output

anonymous class returns: 0
lambda returns: 1

which shows that the value of the postfix decrement expression is the value of the variable after the new value is stored.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Example {
	public static void main(String[] args) throws Exception {
		Supplier<Integer> s1 = new Supplier<Integer>() {
			@Override
			public Integer get(Integer t) {
				return t++;
			}
		};
		System.out.println("anonymous class returns: " + s1.get(0));

		Supplier<Integer> s2 = t -> t++;
		System.out.println("lambda returns: " + s2.get(0));
	}	
}

interface Supplier<T> {
	T get(T t);
}
---------- END SOURCE ----------


Comments
Duplicate of JDK-8038420.
06-04-2014

10: astore_0 is erroneous, the code should be: 0: aload_0 1: invokevirtual #16 // Method java/lang/Integer.intValue:()I 4: iconst_1 5: iadd 6: invokestatic #9 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 9: astore_1 10: aload_0 11: areturn
06-04-2014

it's an issue in javac, not in core-libs: $ javap -p -c Example.class ... private static java.lang.Integer lambda$main$0(java.lang.Integer); Code: 0: aload_0 1: invokevirtual #16 // Method java/lang/Integer.intValue:()I 4: iconst_1 5: iadd 6: invokestatic #9 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 9: dup 10: astore_0 11: astore_1 12: aload_0 13: areturn $ javap -p -c Example\$1.class ... public java.lang.Integer get(java.lang.Integer); Code: 0: aload_1 1: astore_2 2: aload_1 3: invokevirtual #2 // Method java/lang/Integer.intValue:()I 6: iconst_1 7: iadd 8: invokestatic #3 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 11: dup 12: astore_1 13: astore_3 14: aload_2 15: areturn ...
06-04-2014