Method references (version 2008-03-17)
The compiler prototype (available at http://www.javac.info) comes with method references (also known as eta expansion). The method references are written as follows: ClassName # methodName ( listOfArgumentTypes ).
A method reference can be assigned to a function variable:
{ String => int } parseInt = Integer#parseInt(String);
int x = parseInt.invoke("42");
We can use the covariant return:
// Integer.valueOf() returns Integer
{ int => Number } p = Integer#valueOf(int);
System.out.println(p.invoke(97));
And the contravariant arguments:
class MyClass {
static Integer print(Object o) {
return Integer.valueOf(o.hashCode());
}
public static void main(String[] args) {
{ String => Number } pp = MyClass#print(Object);
System.out.println(pp.invoke("hi"));
}
}
An instance method can be referenced in two ways. Either we reference a method on a given object:
class Box {
private int x;
Box(int x) {
this.x = x;
}
int getX() {
return x;
}
}
public class InstanceMethod {
public static void main(String[] args) {
Box p = new Box(10);
{ => int } getX = p#getX();
System.out.println(getX.invoke());
}
}
Or we reference just a method. Then the function type has an additional argument: the object on which the method is called.
{ Box => int } getX = Box#getX(); // additional argument of type Box
Box p = new Box(10);
System.out.println(getX.invoke(p));
The method is selected at runtime according to the object supplied as argument.
So, in the following example, the toString method from String is called.
{ Object => String } toString = Object#toString();
System.out.println(toString.invoke("hi"));
Generic methods are also supported:
{ String => Set<String> } singleton =
Collections#<String>singleton(String);
Set<String> set = singleton.invoke("single");
