gpt4 book ai didi

java - 从泛型获取 ParameterizedType 的类型

转载 作者:行者123 更新时间:2023-12-02 03:38:10 26 4
gpt4 key购买 nike

我无法完全理解反射的工作原理,因此在尝试为我的 GsonBuilder 注册自定义类型适配器时遇到了一些麻烦。 .

我需要为 List<Something> 注册类型适配器类型。

这是一个工作代码:

    gsonBuilder.registerTypeAdapter(
new TypeToken<List<MyClass>>() { }.getType(), new ListDeserializer(MyClass.class)
);

问题是我有很多类来注册我的类型适配器,并且我有一个 ListDeserializerSingleDeserializer适配器。

我试图变得通用,所以我只是调用一个函数,传递我的 GsonBuilder和类(class),就这样。

这是我的尝试:

private static <T> void registerTypeAdapter(GsonBuilder gsonBuilder, T clazz) {
gsonBuilder.registerTypeAdapter(clazz.getClass(), new SingleDeserializer(clazz.getClass()));
gsonBuilder.registerTypeAdapter(
new TypeToken<List<T>>() {
}.getType(), new ListDeserializer(clazz.getClass())
);
}

这对我的 ListDeserializer 不起作用。我的猜测是,自从 TList 的通用参数化类型,它无法在运行时检测到它。

有什么建议吗?

最佳答案

是的,你不能使用new TypeToken<List<T>>() {}.getType()在运行时,由于泛型 type erasureList<T>只是 List<Object>在运行时。但你可以做的是创建 ParameterizedType并使用这样的东西:

Type type = ParameterizedTypeImpl.make(List.class, new Type[]{clazz.getClass()}, null);
gsonBuilder.registerTypeAdapter(type, new ListDeserializer(clazz.getClass()) );

但是你真的需要通用性吗?你可以这样做

private static void registerTypeAdapter2(GsonBuilder gsonBuilder, Class<?> clazz) {
gsonBuilder.registerTypeAdapter(clazz, new SingleDeserializer());
Type type = ParameterizedTypeImpl.make(List.class, new Type[]{clazz}, null);
gsonBuilder.registerTypeAdapter(type, new ListDeserializer());
}

这是演示:

import com.google.gson.*;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

public class Main {
public static void main(String[] args) throws Exception {
GsonBuilder gb = new GsonBuilder();
registerTypeAdapter(gb, MyClass.class);

Gson gson = gb.create();
List data = new ArrayList<>();
data.add(new MyClass("Bob"));
data.add(new MyClass("Alice"));

String listString = gson.toJson(data);
String soloString = gson.toJson(new MyClass("Test"));

Object resultList = gson.fromJson(listString, new TypeToken<List<MyClass>>() {}.getType());
Object resultSolo = gson.fromJson(soloString, MyClass.class);

System.out.println("RESULT:");
System.out.println("FROM " + listString +" TO "+ resultList);
System.out.println("FROM " + soloString +" TO "+ resultSolo);

}

private static void registerTypeAdapter(GsonBuilder gsonBuilder, Class<?> clazz) {
gsonBuilder.registerTypeAdapter(clazz, new SingleDeserializer());
Type type = ParameterizedTypeImpl.make(List.class, new Type[]{clazz}, null);
gsonBuilder.registerTypeAdapter(type, new ListDeserializer());
}

private static class ListDeserializer implements JsonDeserializer {
private static Gson gson = new Gson();

@Override
public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
System.out.println("Used ListDeserializer: Type " + typeOfT);

Type t = (typeOfT instanceof ParameterizedType) ?
((ParameterizedType) typeOfT).getActualTypeArguments()[0] :
Object.class;

Type type = ParameterizedTypeImpl.make(List.class, new Type[]{t}, null);
List list = gson.fromJson(json, type);
return list;
}
}

private static class SingleDeserializer implements JsonDeserializer {
private static Gson gson = new Gson();

@Override
public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
System.out.println("Used SingleDeserializer: Type " + typeOfT);
return gson.fromJson(json, typeOfT);
}
}

public static class MyClass {
@SerializedName("name")
private String name;

public MyClass(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "MyClass{" +
"name='" + name + '\'' +
'}';
}
}
}

关于java - 从泛型获取 ParameterizedType 的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37179759/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com