How to get a Type from class name in Java

Ale*_*exC 2 java gson java-8

I am deserializing json that contains instances of many different classes, using gson. The following works as long as I know all the classes up front:

    String receivedPayloadStr = receivedMessage.get("payload");
    Type payloadType = getType(receivedMessage.get("type").toString());
    Object typedPayload = gson.fromJson(payloadJson, payloadType);
    System.out.println(typedPayload);
Run Code Online (Sandbox Code Playgroud)

My getType function is as follows:

static Type getType(String typeName){
    switch (typeName){
        case "mypackage1.MyThing1":
            return new TypeToken<MyThing1>() {}.getType();
        case "mypackage2.MyThing1":
            return new TypeToken<MyThing2>() {}.getType();
        default:
            throw new RuntimeException("Unsupported type: " + typeName);
    }
}
Run Code Online (Sandbox Code Playgroud)

短期有效,但既丑陋又脆弱。显然,我们想要一种更易于维护的方法。有没有办法以通用方式实现 getType ,以便支持所有已知类?

编辑:我们不仅限于 gson。如果另一个库使任务更容易,我们可以切换到它。

M. *_*rov 5

Gson 的 TokenType 有静态工厂方法,你可以这样使用它:

public Type getType(String name) {
    try {
        Class<?> clazz = Class.forName(typeName);
        TypeToken<?> typeToken = TypeToken.get(clazz);
        return typeToken.getType();
    } catch (ClassNotFoundException e) {
        throw new IllegalArgumentException("Unsupported type: " + typeName, ce);
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该可以帮助您解决大多数不涉及泛型或通配符的情况(或通配符有界的情况,在这种情况下,您应该获得边界上的参数化类型)。

免责声明:我没有测试过这个。

此外,您可能想查看 Guava 的TypeToken版本。