Problem with method references

Tomasz Kowalczewski tomasz.kowalczewski at gmail.com
Sun Jan 2 11:28:42 PST 2011


Hi All,

I got latest code for lambda prototype and started to play with it a
little. I have encountered problems when using method references.

I checked out the code using:

hg clone http://hg.openjdk.java.net/lambda/lambda/langtools

and compiled it against build 1.7.0-ea-fastdebug-b123.

I have following problems when compiling/running my sample code:

1) This example does not compile.

package org.tkowalcz.lambda.extractor;

public class Lambda {

  public static void main( String[] args ) {
    Extractor x = (Extractor) Lambda#getArgCount;
    x.extract( new Lambda() );
  }

  public int getArgCount() {
    return 0;
  }
}

interface Extractor {

  int extract( Lambda lambda );
}

Compiler output (from within ant):

     [exec] src\org\tkowalcz\lambda\extractor\Lambda.java:6: cannot find symbol
     [exec]     Extractor x = Lambda#getArgCount;
     [exec]                   ^
     [exec]   symbol:   method <int>invoke(Lambda)
     [exec]   location: class MethodHandle
     [exec] Fatal Error: Unable to find method invoke

2) After adding a cast to Extractor it will compile but will throw
ClassCastException when run:

public class Lambda {

  public static void main( String[] args ) {
    Extractor x = (Extractor) Lambda#getArgCount;
    x.extract( new Lambda() );
  }

  public int getArgCount() {
    return 0;
  }
}

abstract class Extractor {

  public abstract int extract( Lambda lambda );
}

     [exec] Exception in thread "main" java.lang.ClassCastException:
sun.dyn.DirectMethodHandle cannot be cast to
org.tkowalcz.lambda.extractor.Extractor
     [exec] 	at org.tkowalcz.lambda.extractor.Lambda.main(Lambda.java:6)
     [exec] VM option '+UnlockExperimentalVMOptions'
     [exec] VM option '+EnableInvokeDynamic'

3) However, when I change abstract class Extractor to interface then
removing the cast will let my code compile and run:

public class Lambda {

  public static void main( String[] args ) {
    Extractor x = Lambda#getArgCount;
    x.extract( new Lambda() );
  }

  public int getArgCount() {
    return 0;
  }
}

interface Extractor {

  int extract( Lambda lambda );
}

I hope that 1) and 2) is a correct usage and I am not abusing the
prototype too much.

-- 
Thanks,
Tomasz Kowalczewski


More information about the lambda-dev mailing list