Der Unterschied zwischen xtend(2) dispatch und Javas Methoden-Überladung

Theoretisch gesprochen liegt der Unterschied darin, dass Javas Methoden-Überladung ein „single dispatch“ und xtends „dispatch“ ein „polymorphisches dispatch“ ist. Diese theoretische Aussage wird am Beispiel viel klarer:

Nehmen wir an, wir haben folgende print-Methode, die den Typ und Inhalt eines Parameters ausgibt:


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);
}
}

Das Ergebnis dieser Methode ist „Object abc“! Dazu kommt es, weil der Typ statisch aufgelöst wird, Java also nur die print(Object)-Methode nutzen kann.

Spezifiziert man das Selbe mit xtend(2) kann man polymorphisches dispatch nutzen:

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);
}
}

Jetzt ist die Ausgabe tatsächlich „String: abc“.
Der generierte Code enthält eine Kaskade von if instanceof else Aufrufen. Der obige xtend Beispielcode ergibt folgenden Javacode::

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());
}
}
}

Es wird immer die Methode mit dem speziefischeren Parameter aufgerufen. Mit der Methoden-Überladung von Java wird immer die Methode aufgerufen, die exact der Signatur entspricht.

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.