Java Reference
In-Depth Information
Hier wird bei beiden Aufrufen von m die Methode m der Klasse Y2 benutzt.
Kombiniert man die für sich nicht einfachen Konzepte des Überladens und Überschreibens
einerseits und der Generics andererseits, so kann man leicht Programmcode schreiben, bei
dem nur noch die absolut intimsten Java-Kenner zweifelsfrei wissen, was wirklich passiert.
Wir wollen diesen Bereich nicht vollständig und systematisch behandeln, sondern nur
einige Beispiele ohne nähere Erklärungen angeben, die unterstreichen sollen, wie schwie-
rig das Thema Generics ist.
Betrachten wir zunächst die folgenden Codezeilen:
class A {}
class B<T extends A> {public void m(T t) {}}
class C extends B<A> {public void m(Object obj) {}}
----------------------------------------------------
B<A> b = new C();
b.m(new A());
Welche Methode m wird aufgerufen? Um das zu entscheiden, muss man wissen, ob m in der
Klasse C überladen oder überschrieben wird. Die Antwort lautet: m wird überladen. Des-
halb wird das m der Klasse B aufgerufen. Überschreiben würde so gehen:
class A {}
class B<T extends A> {public void m(T t) {}}
class C extends B<A> {public void m(A a) {}}
Betrachten wir ein ähnliches, aber doch entscheidend anderes Beispiel:
class A {}
class B<T> {public void m(T t) {}}
class C extends B<A> {public void m(Object obj) {}} //Syntaxfehler
Der Java-Compiler meldet für diese Codezeilen den Syntaxfehler “Name clash: The method
m(Object) of type C has the same erasure as m(T) of type B<T> but does not override it”.
Zum Schluss ein letztes, wieder leicht anderes Beispiel:
class A {}
class B<T> {public void m(T t) {}}
class C extends B<A> {public void m(A a) {}}
----------------------------------------------------
B<A> b = new C();
b.m(new A());
In diesem Fall handelt es sich nun tatsächlich um ein Überschreiben, so dass in diesem Fall
die Methode m der Klasse C aufgerufen wird. Die Umsetzung in Byte-Code, in dem keine
Informationen über Generics mehr vorhanden sind, ist allerdings nicht ganz trivial. Denn
wenn man die Typlöschung naiv anwenden würde, ergäbe sich Byte-Code, der zurücküber-
setzt in Java so aussehen würde:
class A {}
class B {public void m(Object t) {}}
class C extends B {public void m(A a) {}}
Das wäre dann aber ein Überladen und kein Überschreiben. Deshalb ist die Umsetzung in
Byte-Code doch etwas trickreicher als hier gezeigt. Auch wenn hier nicht mehr erläutert
 
Search WWH ::




Custom Search