Raw Types

Aus Programmieren-Wiki
🚧 Diese Seite befindet sich in Bearbeitung 🚧
🤓 Diese Seite ist eine Bewertungsrichtlinie, die ab Blatt 2 annotiert und ab Blatt 3 abgezogen wird. 🤓

Beschreibung

Was ist ein "Raw Type"?

In der Dokumentation wird ein Raw Type wiefolgt definiert:

  • Ein Referenztyp der dadurch geformt wird, dass eine generische Typdeklaration ohne Typargument instanziiert wird (Z.B. Liste ohne zugrundeliegenden Typ)
  • Ein Array, dessen Typ ein Raw Type ist
  • Ein nicht-statischer Elementtyp von einem Raw Type R, der nicht von einer Superklasse oder einem Superinterfacfe vererbt wird

Raw Types sind also erstmal stark verbunden mit Generics.

Um den letzten Punkt zu verstehen, schauen wir uns mal folgendes Beispiel aus der Dokumentation an:

class Outer<T>{
    T t;
    class Inner {
        T setOuterT(T t1) { t = t1; return t; }
    }
}

Der Typ der Instanzen von Inner sind also Abhängig von dem Typ, den Outer zugewiesen bekommt. Ist Outer Raw, muss Inner auch als Raw angesehen werden, da keine valide Bindung für T stattgefunden hat. Diese Regel bezieht sich nur auf Typ-Member, die nicht vererbt wurden.

Eine weitere Implikation der Regel ist, dass eine Generische Inner Class mit einem Taw Type kann selbst nur als Raw Type verwendet werden.

class Outer<T>{
    class Inner<S> {
        S s;
    }
}

Es ist also nicht möglich, Inner als halb-Raw Type ("rare" Type) aufzurufen:

Outer.Inner<Double> x = null;  // illegal
Double d = x.s;

Outer ist Raw, also auch alle innere Klassen, damit auch Inner. Also ist es nicht möglich, Typ-Argumente an Inner zu übergeben.


Negativbeispiel

List list = new ArrayList(); // Erstmal kein Fehler
list.add("John");
list.add("Mary");
list.add(Boolean.FALSE); // Bis hierher auch erstmal noch Fehlerfrei

for (Object o : names) {
    String name = (String) o;
    System.out.println(name);
}
// Hier wird eine ClassCastException geworfen, da Boolean.FALSE kein String ist

Positivbeispiel

List<String> list = new ArrayList<>();
list.add("John");
list.add("Mary");
list.add(Boolean.FALSE); // Kompiliert nicht. Die Liste nimmt nur Strings entgegen.

// Ab hier ist Boolean.FALSE nicht mehr in der Liste
for (String s : names) {
    String name = s; // Kein Cast mehr benötigt, da bekannt ist, dass nur Strings vorhanden sind
    System.out.println(name);
}