Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
ich habe eine Frage zum Thema Generics & Reflections.
Ich hätte gerne ein generisches Array:
Java:
public class GenericArray {
public static void main(String[] args) {
Array<String> stringArray = new Array<String>(String.class, 5);
Array<Integer> intArray = new Array<Integer>(Integer.class, 5);
}
}
Code:
public class Array <T> {
private T [] array;
public Array(Class<T> c, int size) {
}
Meine bisherige Lösung schaut wie folgt aus:
Code:
private T [] array;
@SuppressWarnings("unchecked")
public Arrayy(Class<T> c, int size) {
array = (T[]) Array.newInstance(c, size);
}
Die scheint auch zu funktionieren, nur frage ich mich: Gibts nich noch eine "schönere" Möglichkeit?
Ohne Annotationen ala SuppressWarnings?
Oder andersrum: Wie komme ich zur Laufzeit an den Typ von "c" mit Reflections?
Meine bisherigen Ideen waren sonst
Code:
public Arrayy(Class<T> c, int size) {
Type type = c.getGenericSuperclass();
System.out.println(type); // class java.lang.Object, class java.lang.Number
String type2 = c.getCanonicalName();
System.out.println(type2); // java.lang.String, java.lang.Integer
}
Mit dem 2. Ansatz bekomm ich tatsächlich die konkrete Klasse. Hier könnte man wohl nun vielleicht dann mit nem Switch-Case das ganze Fortführen,
aber dann müsste man ja für jeden Typ einen Fall schreiben und das wäre dann ja nicht mehr wirklich "generisch"...
Generics sind für den Compiler, um die Typsicherheit zum Zeitpunkt der Übersetzung (compile time) sicherzustellen. Der Typparameter wird am Ende durch Object ersetzt bzw. entfernt (type erasure).
Es gibt nun verschiedene Möglichkeiten.
Lebe mit SuppressWarnings. Das ist lediglich eine Warnung, weil der Compiler zu doof ist, aber da Du weißt, dass der Code in Ordnung ist, ist das genau einer der Fälle, für die die Annotation gedacht ist.
Arbeite intern mit Object. Hier würde das Array komplett gekapselt, in Zugriffsmethoden wird ggf. nach T gecastet.
Übergebe statt des Elementtyps den Arraytyp, d. h. statt Class<T> eben Class<T[]> als Parameter.
Hier müsstest Du also z. B. GenericArray<String> stringArray = new GenericArray<>(10, String[].class); aufrufen.
Von diesen Möglichkeiten würde ich die erste wählen: SuppressWarnings und gut ist's. Noch besser wäre allerdings, einfach nicht mit Arrays sondern mit einer (Array)List zu arbeiten.
Das ist etwas zu gemein ausgedrueckt, Array.newInstance liefert eben Object als Ergebnis, also die Umwandlung kann oder kann nicht stimmen. Zusammen damit dass der Typ zur Laufzeit nicht geprueft werden kann, ist die Warnung schon richtig. Wieso die damals dann nicht auf <TYPE> TYPE[] newInstanze(Class<TYPE> type, int size) umgestellt haben, weisz ich aber nicht. Wahrscheinlich ging das nicht.