Java 如何创建可添加到列表中的对象<;T>;阵列?

Java 如何创建可添加到列表中的对象<;T>;阵列?,java,generics,Java,Generics,我正在尝试创建一个JSONMessage类,该类可以解析json字符串,并将消息中包含的对象添加到列表t 消息中包含的对象实现了接口JSONSerialization,并实现了两个方法toJSON()和fromJSON() 下面的代码不起作用,因为我无法实例化类型T,并且在行t2.fromJSON…(因为t2尚未初始化)上出现错误 我不确定我在这里的方法是否正确,以及我试图实现的(创建一个通用的JSONMessage)是否可以用于编码/解析不同类型的对象。如果这一方法不可行,我希望得到一些提示,

我正在尝试创建一个JSONMessage类,该类可以解析json字符串,并将消息中包含的对象添加到
列表t

消息中包含的对象实现了接口JSONSerialization,并实现了两个方法toJSON()和fromJSON()

下面的代码不起作用,因为我无法实例化类型T,并且在行
t2.fromJSON…
(因为t2尚未初始化)上出现错误

我不确定我在这里的方法是否正确,以及我试图实现的(创建一个通用的JSONMessage)是否可以用于编码/解析不同类型的对象。如果这一方法不可行,我希望得到一些提示,告诉我如何才能取得类似的结果

问候

接口 等级
public类JSONMessage{
私人名单t;
公共JSONMessage(字符串json){
parseJSONMessage(json);
}
public void parseJSONMessage(字符串json){
试一试{
this.t=新的ArrayList();
JSONObject JSONObject;
JSONArray行项目;
jsonObject=新的jsonObject(json);
this.messageHeader=newmessageheader(jsonObject.getJSONObject(“Header”);
lineItems=jsonObject.getJSONArray(“数据”);
int size=lineItems.length();
对于(int i=0;i
试试这个:

 this.t = new ArrayList<JSONSerialisation>();
this.t=newArrayList();
如果在该方法中删除对该
的所有引用,则可以将其设置为静态。只需在范围中创建一个
列表
,然后返回它


我看不出你买了什么仿制药。您将有多大可能拥有该JSON接口的不同实现?

看起来您正在尝试替换大多数JSON反序列化库中提供的功能。您会注意到,它们中的大多数都需要一个参数化类,作为您所面临问题的解决方案。这不是最优雅的解决方案,但会奏效。我将从反序列化类中删除泛型参数以及有状态变量:

public class JSONMessage {
    public static <T extends JSONSerialisation> Collection<T> parseJSONMessage(Class<T> clazz, String json) {
        try {
            final JSONObject jsonObject = new JSONObject(json);
            final JSONArray lineItems = jsonObject.getJSONArray("Data");

            Collection<T> results = new ArrayList<T>(lineItems.size());

            for (final JSONElement elem: lineItems) {
                T result = clazz.newInstance();
                result.fromJSON(elem);
                results.add(result);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public JSONMessage() {
        super();
    }
}
public类JSONMessage{
公共静态集合parseJSONMessage(类clazz,字符串json){
试一试{
最终JSONObject JSONObject=新JSONObject(json);
最终JSONArray行项=jsonObject.getJSONArray(“数据”);
收集结果=新的ArrayList(lineItems.size());
对于(最终JSONElement元素:行项目){
T result=clazz.newInstance();
result.fromJSON(elem);
结果。添加(结果);
}
}捕获(JSONException e){
e、 printStackTrace();
}
}
公共JSONMessage(){
超级();
}
}

代码显然缺少一些错误处理,我在增强的for循环中编造了一个虚假的
JSONElement
类型,但是您已经了解了一般的想法。祝你好运。

你考虑过在JSON消息中包含对象类吗

一个工厂类实现了
fromJSON(JSONObject)
,这样您就可以创建一个对象的实例,而不必先创建一个对象的实例?工厂可以使用有关生成JSON的上下文的信息来确定适当的Java类。例如,如果您刚刚调用了web服务X,您可能知道响应将是类型为Y的数据块或类型为Z的错误消息

在上面的代码中,如果T有一个子类呢?你如何区分它们

忽略JSON,我想我也应该回答你关于泛型的问题:如果你知道你有一个列表,那么T是什么?Java泛型通过类型擦除来工作,这意味着在编译过程中大量泛型类型信息被擦除。然而,如果您正在将POJO序列化为JSON,则有一个好消息。类、字段和方法保留了泛型类型信息,因此如果您有这样的类:

class Example extends ArrayList<String> {
    private Set<Integer> someIDs;

    public Map<String,Long> getLongMap() {
        ...
    }
}
类示例扩展了ArrayList{
私有集someid;
公共地图getLongMap(){
...
}
}

然后可以使用反射来发现类实现了List,其中T是字符串,
someIDs
字段是Set的一个实例,其中T是整数,
getLongMap
方法返回Map的一个实例,其中K是字符串,V是长的。然而,通过反射API获取这些信息可能会涉及到很多方面。我用来识别集合、迭代器和枚举类型的代码运行了100多行。如果您有其他选择,我不建议尝试这样做。

请在标记中添加语言(我猜它是C#),您没有初始化
t2,但在下一行
t2.fromJSON(…)中使用它。这将抛出一个NPE每次尝试它,看看它是否有帮助。如果没有,请回来。你好@duffymo,谢谢你的建议。我计划使用一个通用的JSON消息类在Servlet和Android应用程序之间来回发送不同类型的对象。我尝试将类设置为静态,但这并不能解决在将其添加到列表之前需要创建新对象(并实例化它)的问题,而且我也无法实例化JSONSerialization类型的对象,因此在尝试将对象添加到列表
ArrayList()时仍然会出错
我认为您应该简化整个方法。谢谢,这正是我想要的。
public class JSONMessage {
    public static <T extends JSONSerialisation> Collection<T> parseJSONMessage(Class<T> clazz, String json) {
        try {
            final JSONObject jsonObject = new JSONObject(json);
            final JSONArray lineItems = jsonObject.getJSONArray("Data");

            Collection<T> results = new ArrayList<T>(lineItems.size());

            for (final JSONElement elem: lineItems) {
                T result = clazz.newInstance();
                result.fromJSON(elem);
                results.add(result);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public JSONMessage() {
        super();
    }
}
class Example extends ArrayList<String> {
    private Set<Integer> someIDs;

    public Map<String,Long> getLongMap() {
        ...
    }
}