Frage

Nehmen Sie wie folgt vor:

public Class<List<String>> getObjectType() {
    // what can I return here?
}

Welche Klasse Literalausdruck kann ich von dieser Methode zurück, die die Generika befriedigen und kompilieren? List.class wird nicht kompiliert, und weder wird List.<String>class.

Wenn Sie sich fragen, „warum“, ich bin eine Implementierung von Spring FactoryBean<List<String>> schreiben, die mich Class<List<String>> getObjectType() umzusetzen erfordert. Dies ist jedoch nicht eine Feder Frage.

bearbeiten. Meine klagende Schreie wurden von den Kräften gehört worden, die bei Springsource, und so Frühling 3.0.1 wird der Rückgabetyp von getObjectType() zu Class<?> haben sich geändert, die fein säuberlich das Problem vermeidet

War es hilfreich?

Lösung

Sie können jederzeit werfen, was Sie brauchen, wie diese

return (Class<List<String>>) new ArrayList<String>().getClass();

oder

return (Class<List<String>>) Collections.<String>emptyList().getClass();

Aber ich nehme an, das ist nicht das, was Sie nach. Nun, es funktioniert, mit einer Warnung, aber es ist nicht gerade „schön“.

ich dies nur gefunden

  

Warum gibt es keine Klasse wörtliche für Wildcard parametrisierte Typen?

     

Da ein Platzhalter parametrisierte Typ keine genaue Laufzeittyp Darstellung hat.

So Gießen könnte den einzigen Weg zu gehen.

Andere Tipps

Sie sollten nie das Konstrukt Class<List<String>> verwenden. Es ist unsinnig, und soll eine Warnung in Java (aber nicht) produzieren. Klasseninstanzen immer rohe Typen darstellen, so können Sie Class<List> haben; das ist es. Wenn Sie etwas ein verdinglichten generischer Typ wie List<String> darstellen wollen, müssen Sie einen „Super-Typ Token“ wie Guice verwendet:

http: //google-guice.googlecode. com / git / javadoc / com / google / inject / TypeLiteral.html

Die Existenz eines Class<List<String>> ist von Natur aus gefährlich. hier ist der Grund:

// This statement generates a warning - for a reason...
Class<List<String>> unsafeListClass = (Class<List<String>>) (Class<?>) List.class;

List<Integer> integerList = new ArrayList<Integer>(); // Ok
integerList.add(42); // Ok

System.out.println(unsafeListClass.isInstance(integerList)); // Prints "true".
List<String> stringList =
   unsafeListClass.cast(integerList); // Succeeds, with no warning!
stringList.add("Hello, World!"); // Also succeeds with no warning

for (int x: integerList) {
    // Compiles without warning, but throws ClassCastException at runtime
    System.out.println(100-x);
}

diesen Link auf springframework.org, die einen Einblick gibt.

z.

List<String> myList = new ArrayList<String>();
return (Class<List<String>>)myList.getClass();

Sie können diese Methode wie folgt implementieren:

public Class<List<String>> getObjectType() {
    return (Class<List<String>>) ((Class)List.class);
}

diese Diskussion Schauen Sie sich auf den SUN-Foren:

http://forums.sun.com/thread.jspa?threadID=5253007

Und die referenzierte Blog-Post, die mit „Super-Typ-Token“ eine Arbeit um beschreibt:

http://gafter.blogspot.com/2006/12 /super-type-tokens.html

Ich bin mir nicht sicher, ob dies überhaupt möglich ist, da wörtliche jede Klasse wird Class.forName(...) kompiliert werden und da dies zur Laufzeit geschieht gibt es keine allgemeinen Informationen verlassen.

Ich bin nicht sicher, aber die folgende Frage, die ich von Bedeutung gefragt könnte sein, dass Sie ...

Java Generics Typ Parameter und Operationen auf diesen Typen

Was folgt aus:

public class TestMain {
    public static void main(String[] args) throws Exception {
        Type type = TestMain.class.getMethod("dummy").getGenericReturnType();
        System.out.println("type = " + type);
    }

    public List<Integer> dummy() {return null;}
}

Dieser Befehl gibt:

type = java.util.List<java.lang.Integer>

Der folgende Ansatz ist problematisch:

> public Class<List<String>> getModelType() {
>   return (Class<List<String>>) new ArrayList<String>().getClass();
> }

z. wenn Sie wollen testen, ob ein Objekt vom Typ sagen

org.eclipse.emf.common.util.BasicEList<String> 

ist vom Typ

List<String> 

basierend auf dem Ergebnis des oben genannten getModelType () Ansatz, zum Beispiel:

BasicEList<String> fromObject = ...;
if (getModelType().isAssignableFrom(fromObject.getClass())) {
    transferFromModelToUi(getModelType().cast(fromObject));
}

es in falschen führen wird, während es wahr sein sollte, weil beiden Objekte die Schnittstelle Liste implementieren (seit getModelType () ein Klasse-Objekt vom Typ Liste zurückgibt und nicht die Arraylist).

Hier ist ein Ansatz, der für mich gearbeitet (ein bisschen umständlich, sondern führen Ergebnisse im Beispiel oben zu korrigieren, zu einem statischen Initialisierer bewegt werden konnte):

public Class<List<String>> getModelType() {
    Class<?> arrayListClass = new ArrayList<String>().getClass();
    Class<?>[] interfaces = arrayListClass.getInterfaces();
    int index = 0;
    for (int i = 0; i < interfaces.length; i++) {
        if (interfaces[i].equals(List.class)) {
            index = i;
            break;
        }
    }
    return (Class<List<String>>) interfaces[index];
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top