如何在 Java 中正确执行以下操作?我想要一个可以创建对象列表的通用例程。在这个例程中,我希望这些对象的类的构造函数支持特定的参数。
澄清一下:我希望这个例程List<T>
从 JSON 字符串创建一个。这是更大的反序列化代码的一部分。如果我能以某种方式指定每个支持T
的实现一个构造函数,该构造函数创建T
给定的 a JSONObject
,那么我可以编写如下例程:
interface CreatableFromJSONObject<T> {
T(JSONObject object); // Complains about missing return type.
}
static <T> List<T extends CreatableFromJSONObject> jsonArrayToList(JSONArray array) {
List<T> result = new ArrayList<T>();
for (int i = 0; i < array.length; ++i) {
JSONObject jsonObject = array.getJSONObject(i);
result.add(T(jsonObject)); // If T has one constructor with 1 one argument JSONObject
}
return result;
}
然后用一个实现这个接口的示例类
class SomeClass implements CreatableFromJSONObject {
SomeClass(JSONObject object) throws JSONException {
// implementation here
}
}
我可以使用所需的方法:
List<SomeClass> list = jsonArrayToList<SomeClass>(someJSONArray);
现在,在 StackOverflow 上对此有相当多的点击,所以我了解到我上面概述的内容是不可能的,因为 Java不支持在接口中指定特定的构造函数,也不支持静态方法(这将是一个替代路线同一件事,但由于同样的原因不可能)。
那么,实现这一目标的最佳方法是什么?
我目前的最佳尝试如下:
public static <T> List<T> jsonArrayToList(final JSONArray jsonArray, Constructor<T> fromJSONObjectConstructor) {
List<T> result = new ArrayList<T>();
try {
for (int i = 0; i < jsonArray.length(); i++) {
result.add(fromJSONObjectConstructor.newInstance(jsonArray.getJSONObject(i)));
}
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (JSONException e) {
throw new RuntimeException(e);
}
return result;
}
然后添加到此方法应支持的每个类:
public class SomeClass {
public static final Constructor<SomeClass> jsonObjectConstructor;
static {
try {
jsonObjectConstructor = CafellowEntity.class.getConstructor(JSONObject.class);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
SomeClass(JSONObject object) throws JSONException {
// Implementation here
}
}
我用作
List<SomeClass> list = jsonArrayToList(myJSONArray, SomeClass.jsonObjectConstructor);
这是我能想到的最漂亮的解决方案,除了根本不使用通用实现之外,只需将(在这种情况下)实际上正在执行工作的几行代码放在我需要它们用于特定的地方班级。
有什么建议么?与替代解决方案相比,此解决方案的性能如何?通过不支持它就像这样 Java 可能告诉我我不应该想要这样做,但这并不能阻止我想知道它。