Method reference assignment compatibility

Mark Mahieu mark at twistedbanana.demon.co.uk
Wed Jul 9 07:17:53 PDT 2008


Neal,

Sorry, I meant to send this reply a couple of weeks ago...

On 26 Jun 2008, at 23:20, Neal Gafter wrote:

>        final class Processor {
>                // ...
>                void process(Message msg) {
>                        //...
>                }
>        }
>
> In Java 6, if I were to alter the process(Message) method to return  
> a value, such as a boolean indicating success or failure of the  
> operation, then I'd break binary compatibility but I think source  
> compatibility would be preserved.
>
> No, this breaks source compatibility.  Another class might extend  
> Processor and implement an interface, and use the inherited process 
> (Message) method as an inherited overrider.
>

I can see how that might apply if only the process method were final,  
but not the Processor class, as in the example.

Thinking about it some more, I'm not convinced that allowing the  
conversion would be the 'right thing' for closure literals in  
general, and nothing I've mentioned seems to warrant having two  
slightly different forms of closure conversion.

More importantly, I've just realised that I forgot to mention that I  
triggered an ArrayIndexOutOfBoundsException in the compiler when I  
first encountered this scenario.  A test case is below, followed by a  
variation using an incompatible number of parameters, which results  
in a slightly different crash.


class ArrayIndexOOBCrash {
	
	public static void main(String[] args) {
		foo(ArrayIndexOOBCrash#bar());
	}
	
	static <T extends {=>void}> void foo(T t) {}
	
	static String bar() { return "value"; }
}

java.lang.ArrayIndexOutOfBoundsException: -1
         at com.sun.tools.javac.jvm.Code$State.pop(Code.java:1686)
         at com.sun.tools.javac.jvm.Code.emitop0(Code.java:828)
         at com.sun.tools.javac.jvm.Items$Item.coerce(Items.java:252)
         at com.sun.tools.javac.jvm.Items$Item.coerce(Items.java:265)
         at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:836)
         at com.sun.tools.javac.jvm.Gen.visitTypeCast(Gen.java:2084)
         at com.sun.tools.javac.tree.JCTree$JCTypeCast.accept 
(JCTree.java:1859)
         at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:834)
         at com.sun.tools.javac.jvm.Gen.visitReturn(Gen.java:1672)
         at com.sun.tools.javac.tree.JCTree$JCReturn.accept 
(JCTree.java:1311)
	...


class MismatchedArgumentListsCrash {
	
	public static void main(String[] args) {
		foo({Object o => "value"});
	}
	
	static <T extends {=>void}> void foo(T t) {}
}

java.lang.AssertionError: mismatched argument lists
         at com.sun.tools.javac.comp.DeClosure$Phase2.visitLambda 
(DeClosure.java:968)
         at com.sun.tools.javac.tree.JCTree$JCLambda.accept 
(JCTree.java:1814)
         at com.sun.tools.javac.tree.TreeTranslator.translate 
(TreeTranslator.java:59)
         at com.sun.tools.javac.tree.TreeTranslator.translate 
(TreeTranslator.java:71)
         at com.sun.tools.javac.tree.TreeTranslator.visitApply 
(TreeTranslator.java:284)
         at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept 
(JCTree.java:1392)
         at com.sun.tools.javac.tree.TreeTranslator.translate 
(TreeTranslator.java:59)
         at com.sun.tools.javac.tree.TreeTranslator.visitExec 
(TreeTranslator.java:243)
         at com.sun.tools.javac.tree.JCTree 
$JCExpressionStatement.accept(JCTree.java:1238)
         at com.sun.tools.javac.tree.TreeTranslator.translate 
(TreeTranslator.java:59)


Regards,

Mark




More information about the closures-dev mailing list