2016-04-26 10 views
0

Zum Beispiel sagen, ich möchte eine Map<Class<?>, List<?>>, also kann ich in eine Klasse und eine Liste von diesem Typ herausbringen - gibt es etwas, das ich die Fragezeichen ersetzen kann, um das zu ermöglichen?Wie erhält man einen Typ mit mehreren generischen Typen, um den Typparametern zu entsprechen?

+0

Wenn Sie „eine Liste dieser Art“ sagen, meinen Sie, dass die Listenelemente vom gleichen Typ wie die Klasse sind? –

+1

Es ist nicht klar, was Sie anstellen. –

+2

ist absolut klar, OP möchte eine Liste von Vögeln mit dem Bird.class Schlüssel und Liste von Katzen mit dem Cat.class Schlüssel speichern – AdamSkywalker

Antwort

4

können Sie den Trick tun, wenn Sie Typprüfung der Methode delegieren:

private class TypedMap { 
    private Map<Class<?>, List<?>> map = new HashMap<>(); 

    public <T> void put(Class<T> key, List<T> value) { 
     map.put(key, value); 
    } 

    @SupressWarnings("unchecked") 
    public <T> List<T> get(Class<T> clazz) { 
     return (List<T>) map.get(clazz); 
    } 
} 
  • Wildcard ? in der Karte Erklärung stellt nicht sicher, dass die Schlüssel Class<?> und Wert List<?> wäre vom gleichen Typ. Methode put() stellt sicher, dass. Sie können map nicht als Map<Class<T>, List<T>> deklarieren, wenn Ihre Klasse nicht generisch ist - deshalb müssen Sie eine Methode verwenden.

  • Get-Methode ist deaktiviert. Die Besetzung ist sicher, wenn Einträge mit put() Methode hinzugefügt werden. (Es gibt immer noch ein Problem mit unformatierten Typen - aber das ist unvermeidbar)

  • Sie können der TypeMap-Klasse weitere Methoden hinzufügen, aber beachten Sie diese Einschränkungen.


public static void main(String[] args) { 
    TypedMap map = new TypedMap(); 
    List<Cat> cats = new ArrayList<>(); 
    List<Dog> dogs = new ArrayList<>(); 
    adder.put(Cat.class, cats); 
    adder.put(Dog.class, dogs); 

    adder.put(Cat.class, dogs); // compilation error 
} 
0

Nicht sicher, was Sie hier erreichen möchten, aber Map<Class<T>, List<T>> wäre die nächste Sache. Die T ist jedoch eine einzelne Klasse Typ, so dass Sie nicht mehrere Klassen in eine Map setzen können.

Sie erhalten eine ClassCastException, wenn Sie versuchen, Objekte verschiedener Klassen in die gleichen Map zu setzen.

2

Java nicht vollständig diese durchzusetzen, sondern eine Möglichkeit, eine Warnung darüber zumindest zu erhalten, durch Verkapselung ist:

public class MyClass { 
    // private, private, private 
    private Map<Class<?>, List<?>> myMap; 

    public <T> void put(Class<T> clazz, List<T> list) { // both must have the same T. 
     myMap.put(clazz, list); 
    } 
    ... 
} 

Sie können immer noch diese brechen, indem sie so etwas wie tun:

MyClass mc = new MyClass(); 
Class c = Main.class;  
List<String> l = new ArrayList<String>();  
mc.put(c, l); 

Aber man zumindest wird eine Warnung über unkontrollierte Umwandlung von c-Class<String> erhalten. Und die unkontrollierte Aufruf von MyClass::put

Verwandte Themen