获取JSON的Java通用函数

获取JSON的Java通用函数,java,json,generics,gson,Java,Json,Generics,Gson,我想从JSON解析对象,它工作得很好,但我想概括我的函数,以获得我想要的每一种类型。我试图使用泛型类型,但它给了我错误 我的代码: //It works, but It's not universal Type type = new TypeToken<List<WeatherParameter>>(){}.getType(); List<WeatherParameter> contactList = new Gson().fromJson(json, typ

我想从
JSON
解析对象,它工作得很好,但我想概括我的函数,以获得我想要的每一种类型。我试图使用泛型类型,但它给了我错误

我的代码:

//It works, but It's not universal
Type type = new TypeToken<List<WeatherParameter>>(){}.getType();
List<WeatherParameter> contactList = new Gson().fromJson(json, type);

//My function:
public static <T> List<T> getArrayFromJSON(String json) {
        Type type = new TypeToken<List<T>>(){}.getType();
        return new Gson().fromJson(json, type);
    }

Usage:
List<WeatherParameter> contactList = getArrayFromJSON(json);

//Error:
com.google.gson.internal.LinkedTreeMap cannot be cast to com.entity.model.WeatherParameter.
它在
list.add(clazz.cast(o))行崩溃,错误相同:
ClassCastException

完整堆栈跟踪:

java.lang.ClassCastException: Cannot cast com.google.gson.internal.LinkedTreeMap to com.entity.model.WeatherParameter
    at java.lang.Class.cast(Class.java:3361)
    at com.server.utils.JsonUtils.getArrayFromJSON(JsonUtils.java:23)
    at com.server.task.ShowDataTask.process(ShowDataTask.java:21)
    at com.server.task.AbstractTask.run(AbstractTask.java:16)
    at com.server.utils.TaskUtils.lambda$doGet$1(TaskUtils.java:17)
    at com.server.utils.TaskUtils$$Lambda$22/18975860.handle(Unknown Source)
    at spark.RouteImpl$1.handle(RouteImpl.java:61)
    at spark.http.matching.Routes.execute(Routes.java:61)
    at spark.http.matching.MatcherFilter.doFilter(MatcherFilter.java:128)
    at spark.embeddedserver.jetty.JettyHandler.doHandle(JettyHandler.java:50)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:189)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
    at org.eclipse.jetty.server.Server.handle(Server.java:534)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)
    at java.lang.Thread.run(Thread.java:745)
正如我所说,JsonUtils中有23行:
list.add(clazz.cast(o))
我这样称呼它:

List<WeatherParameter> weatherParameterList = JsonUtils.getArrayFromJSON(json, WeatherParameter.class);
List weatherParameterList=JsonUtils.getArrayFromJSON(json,WeatherParameter.class);

泛型方法编译失败的基本原因是在类型擦除之后,
getArrayFromJSON()
方法返回一个
列表,而不是
列表。假设编译器允许您的代码通过。然后,您可以将对象列表指定给天气参数列表。但并非每个对象都是天气参数,因此这可能会在类强制转换异常中失败

解决这个问题的一种方法是将
WeatherParameter
类的类型信息传递给您的自定义方法,即

public static <T> List<T> getArrayFromJSON(String json, Class<T> clazz) {
    // use class information somehow...
}
public静态列表getArrayFromJSON(字符串json,类clazz){
//以某种方式使用类信息。。。
}
由于GSON库中可能需要类信息,因此您可能会遇到困难

看看下面的问题来思考这个问题:


泛型方法编译失败的基本原因是在类型擦除之后,
getArrayFromJSON()
方法返回一个
列表,而不是
列表。假设编译器允许您的代码通过。然后,您可以将对象列表指定给天气参数列表。但并非每个对象都是天气参数,因此这可能会在类强制转换异常中失败

解决这个问题的一种方法是将
WeatherParameter
类的类型信息传递给您的自定义方法,即

public static <T> List<T> getArrayFromJSON(String json, Class<T> clazz) {
    // use class information somehow...
}
public静态列表getArrayFromJSON(字符串json,类clazz){
//以某种方式使用类信息。。。
}
由于GSON库中可能需要类信息,因此您可能会遇到困难

看看下面的问题来思考这个问题:


这是编译时错误还是运行时错误?在哪一行报告?这是整个错误消息还是被截断了?@KlitosKyriacou当我想使用列表中的项时,它会出现,比如:
System.out.println(contactList.get(0.getId())您能提供完整的堆栈跟踪吗?这是编译时错误还是运行时错误?在哪一行报告?这是整个错误消息还是被截断了?@KlitosKyriacou当我想使用列表中的项时,它会出现,比如:
System.out.println(contactList.get(0.getId())你能提供一个完整的堆栈跟踪吗?这个代码看起来并不遥远。也许您可以通过第二次尝试来更新您的问题。@KurdTt-您需要在这一行使用clazz:
Type Type=new-TypeToken(){}.getType()而不是使用T(在运行时被擦除)。此代码看起来并不遥远。也许您可以通过第二次尝试来更新您的问题。@KurdTt-您需要在这一行使用clazz:
Type Type=new-TypeToken(){}.getType()而不是使用T(在运行时被擦除)。