39

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

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

4

5 に答える 5

35

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

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

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

于 2010-11-09T12:46:55.397 に答える
25

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で説明されているように

于 2010-11-09T12:51:28.487 に答える
7

ソリューションは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;
于 2010-11-09T13:02:14.967 に答える
3

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

于 2010-11-09T12:47:03.880 に答える
2

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

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

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

于 2010-11-09T12:46:22.493 に答える