web-dev-qa-db-ja.com

Javaで、リフレクションを使用して引数なしのコンストラクターなしでクラスの「空白」インスタンスを作成することは可能ですか?

デフォルトのコンストラクターを持たないクラスがあります。そして、このクラスの「空白」インスタンスを取得する方法が必要です。 「空白」は、インスタンス化後、すべてのクラスフィールドにnull、0などのデフォルト値が必要であることを意味します。

オブジェクトの大きなツリーをシリアル化/非シリアライズできる必要があるため、質問しています。そして、私はこのオブジェクトのソースにアクセスできません。クラスとクラスにはデフォルトのコンストラクターもシリアル化可能な実装もありません。このような構造をシリアル化することはあまり良い考えではありませんが、代わりに、より簡単にシリアル化できるものに変換することもできます。

35
Vladimir

標準のリフレクションではありませんが、それを実行できるライブラリがあります: objenesis

これは、デフォルトのコンストラクターなしでクラスをインスタンス化するように特別に設計されており、 xstream などの他のシリアル化ライブラリーによって使用されます。

注:これらの場合、コンストラクターは呼び出されない可能性があります(ただし、おそらくそれが必要です)。

33
Brad Cupit

Classインスタンスを変数clazzとして提供する:

ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Constructor objDef = parent.getDeclaredConstructor();
Constructor intConstr = rf.newConstructorForSerialization(clazz, objDef);
clazz.cast(intConstr.newInstance());

http://www.javaspecialists.eu/archive/Issue175.html で説明されているように

20
mcveat

ソリューションはJVM固有になります。

ポータブルソリューションが必要な場合は、サードパーティのライブラリを使用してください

SunのJVMv1.5の場合、これを行うことができます。

    final Class<?> myClass = MyClass.class;
    final ReflectionFactory reflection = ReflectionFactory.getReflectionFactory();
    final Constructor<Object> constructor = 
        reflection.newConstructorForSerialization(
            myClass, Object.class.getDeclaredConstructor(new Class[0]));
    final Object o = constructor.newInstance(new Object[0]);

    System.out.print(o.getClass());

XStreamの関連クラスは次のとおりです。

  • com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider
  • com.thoughtworks.xstream.core.JVM;
6
johnstok

私が考えることができる唯一の解決策は、 javassist などのバイトコード操作ライブラリを使用してデフォルトのコンストラクタを追加することです。

3
Maurice Perry

クラスに他のコンストラクターがない場合、コンパイラーがコンストラクターを作成します。引数のないコンストラクターがあり、それを認識していない可能性があります。

引数なしのコンストラクターを作成せず、引数を取る1つでもコンストラクターを含めると、コンパイラーは引数を提供しません。リフレクションも役に立ちません。引数のないコンストラクターを見つけようとして、コンストラクターがない場合、どうなると思いますか?

Java Java.lang.Serializableを使用したオブジェクトのシリアル化を使用できるようには思えませんが、それが唯一の選択肢ではありません。XML、JSON、プロトタイプバッファー、またはその他を使用することもできます。便利な他のプロトコル。

2
duffymo