如何创建可以添加到List <t>数组的对象?</t>

时间:2012-03-18 12:39:15

标签: java generics

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

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

下面的代码不起作用,因为我无法实例化Type T,并且我在行t2.fromJSON...上收到错误(因为t2尚未初始化)。

我不确定我的方法是否正确以及我尝试的是否可以实现(创建一个通用的JSONMessage),我可以使用它来编码/解析不同类型的对象。如果不可能采用这种方法,我会很感激如何获得类似的结果。

此致

接口

public interface JSONSerialisation {
    public JSONObject toJSON();
    public void fromJSON(JSONObject jsonObject);
}

public class JSONMessage<T extends JSONSerialisation> {

    private List<T> t;

    public JSONMessage(String json) {
        parseJSONMessage(json);
    }

    public void parseJSONMessage(String json) {
        try {
            this.t = new ArrayList<T>();
            JSONObject jsonObject;
            JSONArray lineItems;
            jsonObject = new JSONObject(json);
            this.messageHeader = new MessageHeader(jsonObject.getJSONObject("Header"));

            lineItems = jsonObject.getJSONArray("Data");
            int size = lineItems.length();

            for (int i = 0; i < size; i++) {
                T t2;
                t2.fromJSON(lineItems.getJSONObject(i));
                t.add(t2);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

}

3 个答案:

答案 0 :(得分:0)

试试这个:

 this.t = new ArrayList<JSONSerialisation>();

如果删除该方法中对this的所有引用,则可以将其设置为静态。只需在范围内创建List并将其返回。

我不知道仿制药在这里买了什么。您将有多少可能拥有该JSON接口的不同实现?

答案 1 :(得分:0)

看起来您正在尝试替换大多数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();
    }
}

代码显然缺少一些错误处理,我在增强的for循环中编写了一个伪造的JSONElement类型,但是你得到了一般的想法。祝你好运。

答案 2 :(得分:0)

您是否考虑在JSON消息中包含对象类?

如何实现fromJSON(JSONObject)的工厂类,以便在不首先拥有对象实例的情况下创建对象的实例?工厂可以使用有关生成JSON的上下文的信息来确定适当的Java类。例如,如果您刚刚调用了Web服务X,则可能知道响应将是Y类型的数据或Z类型的错误消息。

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

忽略JSON,我想我也会回答关于泛型问题的部分:如果你知道你有一个List,那么T是什么? Java泛型通过类型擦除工作,这意味着在编译期间,许多泛型类型信息被擦除。但是,如果您将POJO序列化为JSON,那就有好消息。对于类,字段和方法保留泛型类型信息,因此如果您有类似这样的类:

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

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

然后可以使用反射来发现该类实现List,其中T是String,someIDs字段是Set的实例,其中T是Integer,getLongMap方法返回一个实例其中K是String而V是Long的Map。但是,通过反射API工作以获取此信息可能会非常复杂。我只能识别Collection,Iterator和Enumeration类型的代码可以运行超过100行。如果您有其他选择,我不建议您尝试这样做。