Javaで次のことを正しく行うには? オブジェクトのリストを作成できる汎用ルーチンが必要です。このルーチンでは、これらのオブジェクトのクラスのコンストラクターが特定のパラメーターをサポートすることを期待しています。
List<T>
明確にするために: このルーチンで JSON 文字列からを作成したいと思います。これは、より大きな逆シリアル化コードの一部です。サポートされているそれぞれが、指定された を作成するT
コンストラクターを実装することをどうにかして指定できれば、ルーチンを次のように書くことができます。T
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のようにサポートしないことで、おそらくこれをしたくないと言っているのでしょうが、とにかくそれについて疑問に思うことを妨げるものではありません.