casting ArrayList.toArray() die ArrayList mit Generischen Arrays

Ist eine schwierige Frage, die ich bin nahe dran aufzugeben, alle Hoffnung auf. Ich versuche, mich ein
Funktion, aber ich habe Probleme bei der Anreise ArrayList.toArray() Rückkehr der Typ den ich haben will.

Hier ist das minimal-Beispiel, das veranschaulicht mein problem:

public static <T> T[] test(T one, T two) {
    java.util.List<T> list = new ArrayList<T>();
    list.add(one);
    list.add(two);
    return (T[]) list.toArray();
}

Normalerweise würde ich in der Lage sein, um das Formular zu verwenden (T[]) list.toArray(new T[0]) aber es gibt zwei zusätzliche Schwierigkeiten:

  1. Wegen der Kovarianz-Regeln, die ich nicht festgelegten arrays (T[]) myObjectArray gibt eine ClassCastException
  2. Sie können nicht erstellen Sie eine neue Instanz eines generischen Typs, d.h. ich kann keine Instanz new T[]. Noch kann ich Klon auf eines der Elemente der ArrayList oder versuchen, sich in seine Klasse.

Ich habe versucht, einige Informationen über den folgenden Aufruf:

public static void main(String[] args) {
   System.out.println(test("onestring", "twostrings"));
}

das Ergebnis ist von der form [Ljava.lang.Object;@3e25a5 was darauf hindeutet, dass der typecast auf die Rücksendung nicht wirksam. seltsamerweise sind die folgenden:

public static void main(String[] args) {
    System.out.println(test("onestring", "twostrings").getClass());
}

kommt zurück mit:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
at patchLinker.Utilities.main(Utilities.java:286)

Also meine beste Vermutung ist, dass es glaube ist es ein String-array label klug, aber intern ist ein Objekt-array, und alle versuche, access bringt, dass inconsistancy aus.

Wenn jemand finden können jede Art von arbeiten rund um das (da die beiden normalen workarounds sind mir verwehrt), wäre ich sehr dankbar.

K. Barad
JDK1.6


Bearbeiten


Danke an Peter Lawrey für die Lösung des ursprünglichen Problems. Nun die Frage ist, wie die Lösung für meine weniger triviales Beispiel:

public static <T> T[] unTreeArray(T[][] input) {
    java.util.List<T> outList = new ArrayList<T>();
    java.util.List<T> tempList;
    T[] typeVar;
    for (T[] subArray : input) {
        tempList = java.util.Arrays.asList(subArray);
        outList.addAll(tempList);
    }
    if (input.length > 0) {
        typeVar = input[0];
    } else {
        return null;
    }
    return (T[]) outList.toArray((T[]) java.lang.reflect.Array.newInstance(typeVar.getClass(),outList.size()));
}

public static void main(String[] args) {
    String[][] lines = { { "111", "122", "133" }, { "211", "222", "233" } };
    unTreeArray(lines);
}

Das Ergebnis im moment ist

Exception in thread "main" java.lang.ArrayStoreException
at java.lang.System.arraycopy(Native Method)
at java.util.ArrayList.toArray(Unknown Source)
at patchLinker.Utilities.unTreeArray(Utilities.java:159)
at patchLinker.Utilities.main(Utilities.java:301)

Ich bin immer noch tun einige tests, um zu sehen, wenn ich mehr nützliche Informationen als das, aber im moment bin ich nicht sicher, wo zu beginnen. Ich werde alle weitere Informationen, die ich bekommen wie ich es bekommen.

K. Barad


edit 2


Einige Sie jetzt weitere Informationen an. Ich habe versucht, zu bauen das array manuell und übertragen Sie die Elemente in elementweise, so würde ich typecasting als T, sondern als T[]. Ich fand ein Interessantes Ergebnis:

public static <T> T[] unTreeArray(T[][] input) {
    java.util.List<T> outList = new ArrayList<T>();
    java.util.List<T> tempList;
    T[] outArray;
    for (T[] subArray : input) {
        tempList = java.util.Arrays.asList(subArray);
        outList.addAll(tempList);
    }
    if (outList.size() == 0) {
        return null;
    } else {
        outArray = input[0];//use as a class sampler
        outArray =
                (T[]) java.lang.reflect.Array.newInstance(outArray.getClass(), outList.size());
        for (int i = 0; i < outList.size(); i++) {
            System.out.println(i + "  " + outArray.length + "   " + outList.size() + "   "  + outList.get(i));
            outArray[i] = (T) outList.get(i);
        }
        System.out.println(outArray.length);
        return outArray;
    }
}

Ich bekomme immer noch folgende Ausgabe:

0  6   6   111
Exception in thread "main" java.lang.ArrayStoreException: java.lang.String
at patchLinker.Utilities.unTreeArray(Utilities.java:291)
at patchLinker.Utilities.main(Utilities.java:307)

Bedeutet dies, dass Sie nicht schreiben können, um ein T[] selbst wenn es Ihnen gelingt zu erstellen eine indirekt?

  • Ich schlage vor, kleben mit Sammlungen und verlassen hinter der alten Schule Referenz-arrays.
  • Würde gerne, aber es gibt Zeiten, wenn Sie haben keine Wahl in der Angelegenheit. Rückwärts-Kompatibilität bedeutet immer, dass etwas rückständig.
InformationsquelleAutor K.Barad | 2011-01-19
Schreibe einen Kommentar