2016-05-11 2 views
1

Wenn ElementType ist eine statisch bekannte Art, es „easy“ ist ein Type Objekt repräsentiert eine Sammlung von ElementType s zu erstellen:Get ParametrizedType Objekt von dynamischem Elementtyp

Type listType = new TypeToken<ObservableList<ElementType>>(){}.getType(); 

Aber das ist hier nicht möglich, da mein elementType ist ein dynamischer Wert, erst zur Laufzeit bekannt:

@Override 
public ListProperty<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws 
     JsonParseException { 
    Type elementType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0]; 
    Type listType = // ??? create the type representing a ObservableList<elementType> 
    ObservableList<?> list = context.deserialize(json, listType); 
    return new SimpleListProperty<>(list); 
} 

Jetzt würde ich gerne einen listTypeObservableList<>, welcher Typ Parameter darstellen sollte der Wert von 012 sein. Gibt es einen Weg dazu?

+0

Ich bin co nfused, worauf sich elementType bezieht? Was meinst du mit _dynamic_? Woher kommt es? –

+0

@SotiriosDelimanolis Ich schreibe einen benutzerdefinierten JSON Deserializer für irgendeine Art von Liste. Der Typ dieser Liste wird als Parameter Typ TypOfT für meine Methode angegeben. Jetzt sollte mein Deserializer die Arbeit durch Deserialisierung als eine andere Art von Liste aufschieben, also muss ich die 'typeOfT' für diese andere Art selbst erstellen. – Joffrey

+0

Siehe [hier] (http://stackoverflow.com/a/25223817/438154). –

Antwort

0

Wie in this post vorgeschlagen, landete ich meine eigene Implementierung von ParametrizedType Erstellung bis:

private static class CustomParameterizedType implements ParameterizedType { 

    private Type rawType; 
    private Type ownerType; 
    private Type[] typeArguments; 

    private CustomParameterizedType(Type rawType, Type ownerType, Type... typeArguments) { 
     this.rawType = rawType; 
     this.ownerType = ownerType; 
     this.typeArguments = typeArguments; 
    } 

    @Override 
    public Type[] getActualTypeArguments() { 
     return typeArguments; 
    } 

    @Override 
    public Type getRawType() { 
     return rawType; 
    } 

    @Override 
    public Type getOwnerType() { 
     return ownerType; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) { 
      return true; 
     } 
     if (o == null || getClass() != o.getClass()) { 
      return false; 
     } 
     CustomParameterizedType that = (CustomParameterizedType) o; 
     return Objects.equals(rawType, that.rawType) && 
       Objects.equals(ownerType, that.ownerType) && 
       Arrays.equals(typeArguments, that.typeArguments); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(rawType, ownerType, typeArguments); 
    } 
} 

Und dann konnte ich es auf diese Weise verwenden:

@Override 
public ListProperty<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws 
     JsonParseException { 
    Type elementType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0]; 
    Type listType = new CustomParametrizedType(ObservableList.class, null, elementType); 
    ObservableList<?> list = context.deserialize(json, listType); 
    return new SimpleListProperty<>(list); 
} 
1

Wenn Sie Guava haben, können Sie ihre Version von TypeToken die bietet, was Sie brauchen:

static <T> TypeToken<ObservableList<T>> mapToken(TypeToken<T> typeParameter) { 
    return new TypeToken<ObservableList<T>>() {}.where(new TypeParameter<T>() {}, typeParameter); 
} 

@Override 
public ListProperty<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws 
     JsonParseException { 
    Type elementType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0]; 
    Type listType = mapToken(TypeToken.of(elementType)).getType(); 
    ObservableList<?> list = context.deserialize(json, listType); 
    return new SimpleListProperty<>(list); 
} 
+0

Danke für die Antwort, aber ich würde lieber nicht nur eine Abhängigkeit von Guava hinzufügen, da ich es nicht bereits verwende. – Joffrey