The difference of xtend(2) dispatch and Java’s method override

The difference is single dispatch vs polymorphic dispatch. This theoretical concept becomes more clear with a comprehensive example:

Let’s assume we have a method print which is printing the type of an argument along this the content. With method overloading the java code would look like this:


public class Printer {
public void print(String str) {
System.out.println("String: "+str);
}
public void print(Object obj) {
System.out.println("Object: "+obj);
}
public static void main(String[] args) {
Object obj = new String("abc");
new Printer().print(obj);
}
}

The result of this method is “Object abc”! This happens, because the type is statically resolved at compile time, so only print(Object) can be bound.

When specifying this construct with xtend(2) we can use real polymorphic method dispatching:

class Printer {
def dispatch print(String str) {
"String: "+str
}

def dispatch print(Object obj) {
"Object: "+obj
}

def static void main(String[] args) {
val Object obj = new String("abc");
new Printer().print(obj);
}
}

The result would really be “String: abc”.
The generated code is made up of if instanceof else cascades. For the two dispatch methods in the example above the following Java code would be generated:

import java.util.Arrays;
import org.eclipse.xtext.xbase.lib.StringExtensions;

@SuppressWarnings("all")
public class Printer {
protected String _print(final String str) {
String _operator_plus = StringExtensions.operator_plus("String: ", str);
return _operator_plus;
}

protected String _print(final Object obj) {
String _operator_plus = StringExtensions.operator_plus("Object: ", obj);
return _operator_plus;
}

public static void main(final String[] args) {
String _string = new String("abc");
final Object obj = _string;
Printer _printer = new Printer();
_printer.print(obj);
}

public String print(final Object str) {
if (str instanceof String) {
return _print((String)str);
} else if (str != null) {
return _print(str);

} else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.asList(str).toString());
}
}
}

This way the method with the more specific parameter is choosen, while using java's normal method overloading the method with the exact signiture as called for is taken.

Sources & kudos:
http://www.2ality.com/2009_05_01_archive.html
and
http://www.eclipse.org/xtend/documentation/index.html#polymorphicDispatch

Leave a Reply

Your email address will not be published. Required fields are marked *