我如何使用泛型类的构造函数

时间:2013-02-26 14:56:30

标签: java generics

我有多个基本相同的课程。我在构造函数中传递一个JSONObject,它设置了一些变量。

现在我得到了一些其他类来创建第一个类并将它们添加到ArrayList中。现在我想使用泛型将第二个类合并为一个。

这就是我想要做的事情:

 public class Data<T> {
     public ArrayList<T> data;

     public Data(String response1) {
         data = new ArrayList<T>();
         JSONArray ja;

         try {
              ja = new JSONArray(response1);
              for (int i = 0; i < ja.length(); i++) {
                  JSONObject jo = (JSONObject) ja.get(i);
                  data.add(new T(jo));
              }
         } catch (JSONException e) {
              e.printStackTrace();
         }
     }
 }

但它不允许我用

创建一个T实例
new T(jo);

如果有人可以帮助我会很好

2 个答案:

答案 0 :(得分:3)

这种情况有一个标准技巧:将Class<T>String data一起传递到调用中,然后为JSONObject添加一个setter。这将允许您调用无参数构造函数,如下所示:

interface WithJson {
    void setJson(JSONObject jo);
}

public class Data<T extends WithJson> {
    public Data(String response1, Class<T> type) {
        data = new ArrayList<T>();
        JSONArray ja;
        try {
             ja = new JSONArray(response1);
             for (int i = 0; i < ja.length(); i++) {
                 JSONObject jo = (JSONObject) ja.get(i);
                 T obj = type.newInstance();
                 object.setJson(jo);
                 data.add(obj);
             }
        } catch (JSONException e) {
             e.printStackTrace();
        }
    }
}

在Java 5中修改了Class<T>,以便将其用作该类实例的工厂。静态检查type.newInstance的调用是否类型安全。添加接口WithJson允许您以setJson的实例调用T方法,以便编译器可以静态检查。

构造Data<T>时,需要传递正在创建的类,如下所示:

Data<MyContent> d = new Data(jsonString, MyContent.class);

答案 1 :(得分:0)

使用通用工厂界面。

public interface Factory<T>
{
    public T createFromJSONObject( JSONObject jo );
}

现在是一个修改过的构造函数:

 public Data(
   String response1,
   Factory<T> factory
 ) {
     data = new ArrayList<T>();
     JSONArray ja;

     try {
          ja = new JSONArray(response1);
          for (int i = 0; i < ja.length(); i++) {
              JSONObject jo = (JSONObject) ja.get(i);
              data.add( factory.createFromJSONObject( jo ) );
          }
     } catch (JSONException e) {
          e.printStackTrace();
     }
 }