Generic - Verstädnisproblem

oSnake

Mitglied
Hallo Leute,

folgender Code
Code:
class A { };
class B extends A { };
class C extends B { };
class D extends B { };
class E { };

class X {
  public static <T> T   f(T[]               a, Feld<? extends T> b) { return null; }
  public static <T> T[] g(Feld<? extends T> a, Feld<? super T>   b) { return null; }
}

public class Test {
  public static void main(String[] args) {

        //Anweisungen
    A        x01 = X.f(new B[3],                new FeldFix<D>(8));
    Object[] x02 = X.f(new C[2],                new FeldFix<D[]>(8));
    Feld     x03 = X.f(new FeldFix[4],          new FeldFix<FeldFix<A>>(8));
    A[]      x05 = X.g(new FeldFix<B>(8),       new FeldFix<B>(8));
    B[]      x06 = X.g(new FeldFix<B>(8),       new FeldFix<A>(8));
    C[]      x07 = X.g(new FeldFix<B>(8),       new FeldFix<A>(8));
    C[]      x08 = X.g(new FeldFix<C>(8),       new FeldFix<A>(8));
    C[]      x09 = X.g(new FeldFix<A>(8),       new FeldFix<C>(8));
    C[]      x10 = X.g(new FeldFix<D>(8),       new FeldFix<B>(8));
    Object   x11 = X.g(new FeldFix<B>(8),       new FeldFix<D>(8));
    B[]      x12 = X.g(new FeldFix<A>(8),       new FeldFix<Object>(8));
    A[]      x13 = X.g(new FeldFix<B>(8),       new FeldFix<Object>(8));
    Object   x14 = X.g(new FeldFix<C[]>(8),     new FeldFix<A[]>(8));
    Object   x15 = X.g(new FeldFix<Feld<C>>(8), new FeldFix<Feld<A>>(8));
    Object   x16 = X.g(new FeldFix<Feld<C>>(8), new FeldFix<Feld>(8));
  }
}

die Frage vom Prof ist hier = Welche der folgenden Anweisungen werden vom Compiler akzeptiert, welche nicht?


Leider blick ich absolut nicht durch was die Methoden f und g hier machen.
 
Im Endeffekt machen sie gar nichts, da sie immer null zurückgeben.
Bei der Aufgabe geht es eher darum zu verstehen wie Generics funktionieren.

Die Funktion f erwartet ein Array eines beliebigen Typs (T), sowie ein Objekt vom Typ Feld, wobei Feld wieder generisch ist. Das besondere ist hierbei, dass der generische Typ des Feldes von dem Typ T erben muss.

Wenn du also ein Array vom Typ XYZ übergibst, und ein Feld<ABC>, dann ist dass nur korrekt, wenn ABC auch von XYZ erbt
 
Danke erstmal für die schnelle Antwort 🙂 !

Demnach wird also die Anweisung

A x01 = X.f(new B[3], new FeldFix<D>(8));

akzeptiert da D von B erbt,

Object[] x02 = X.f(new C[2], new FeldFix<D[]>(8));

wiederum nicht da D nicht von C erbt?


Muss ich hier nicht auch beachten in welcher Klasse die Methode gestartet wird?
 
erstmal musst du auch die Rückgabe beachten. Wenn du den Typ XYZ[] übergibst, wird der Typ XYZ zurückgegeben.

Code:
Object[] x02 = X.f(new C[2], new FeldFix<D[]>(8));
Hier musst du aufpassen, Dem Feld wird nicht der Typ D übergeben, sondern der Typ D[], also ein Array von D. Selbst wenn D also von C erben würde, würde es nicht gehen, da eben D[] übergeben wird.
Außerdem passt hier die Rückgabe auch nicht, da f zwar ein C Array als Parameter bekommt, aber nur ein einzelnes C zurückgibt. Object[] x02 ist aber offensichtlich eben nicht vom Typ C
 
Auf Grund der statischen Typisierung, wird vom Compiler geprüft, ob eine Zuweisung auch erlaubt ist. Und der Compiler sieht eben an Hand der Signatur, dass f eben einen bestimmten Typen (T) zurückgibt. Dass die Methode effektiv nie ein konkretes Objekt, sondern nur null zurückgibt, ist dabei nicht von Bedeutung. Der Compiler betrachtet hier nur die Signatur
 

Zurück
Oben