6

FieldJavaReflectionを介してString値を特定のオブジェクトデータ型に変換できるメソッドを構築したいと思います。

これが私のコードです:

String value = ...;

Class<? extends MyObject> clazz = getClazz();

Field f = clazz.getDeclaredField("fieldName");
boolean fieldIsAccessible = f.isAccessible();
if (!fieldIsAccessible) {
   f.setAccessible(true);
}

f.getType().cast(value);

if (!fieldIsAccessible) {
    f.setAccessible(false);
}

このコードを最初の試行で実行すると、この例外が発生しますjava.lang.ClassCastException

valueクラスに変換したいjava.math.BigDecimal

私のコードには何がありませんか?

編集: 私が思いついた解決策を表示します。

4

10 に答える 10

11

次のような文字列コンストラクターを持つクラスでこれを機能させることができます。 f.getType().getConstructor( String.class ).newInstance( value );

于 2012-11-26T16:52:19.367 に答える
3

Javaには、文字列を任意のクラスのインスタンスに変換するための普遍的な方法はありません。多くのクラスは、単にそのような変換をサポートしていません。そして、それをサポートしている人のための標準的なインターフェースはありません。

最善の策は、Stringを唯一の引数として受け入れるコンストラクターを探すことです。もちろん、すべてのクラスがそのようなコンストラクターを提供するわけではなく、セマンティクスが期待どおりになるという保証はありません。

于 2012-11-26T16:44:13.580 に答える
3

文字列値を目的のデータ型に変換する type-parser と呼ばれる Github プロジェクト (MIT ライセンス) があります。

ここにGitHubからのプロジェクトの説明があります

これは、文字列を特定の型に解析するだけの軽量ライブラリです。Integer、File、Enum、Float などの該当するすべての Java クラスをサポートします。これには、List、Set、Map、配列、さらにはカスタムメイドの型などの一般的な Collection 型/インターフェイスも含まれます。独自のパーサーを登録することも可能です。

于 2015-04-15T13:47:11.273 に答える
1

maerics が言ったように、文字列をデータ型にキャストすることはできません。「文字列から BigDecimal を解析するにはどうすればよいですか」という意味ですか?

fieldName = new BigDecimal(value);
于 2012-11-26T16:45:34.310 に答える
1

それを行う一般的な方法がないため、文字列をJava型に変換する方法の質問におそらく答えていません。しかし、これに役立つライブラリがあります。型パーサーライブラリを参照してください。上記のコードをスナイプすると、次のようになります。

    String value = ...;

    Class<? extends MyObject> clazz = getClazz();

    Field f = clazz.getDeclaredField("fieldName");
    boolean fieldIsAccessible = f.isAccessible();
    if (!fieldIsAccessible) {
       f.setAccessible(true);
    }

    TypeParser parser = TypeParser.newBuilder().build();

    // parse value to whatever type f.getGenericType() returns
    Object o = parser.parseType(value, f.getGenericType());


    if (!fieldIsAccessible) {
        f.setAccessible(false);
    }
}
于 2014-04-14T11:27:22.247 に答える
1

クラス キャスト メソッドは、オブジェクトが null ではなく、型 T に割り当てることができない場合、ClassCastException をスローします。文字列参照を割り当てることができる変数の型は、String、Object、Serializable、Comparable、および CharSequence のみです。

すべてではありませんが、多くのクラスには、String に基づいてオブジェクト インスタンスを生成する方法があります。BigDecimal を含む場合によっては、新しいオブジェクトの値の文字列表現を取るコンストラクターがあります。単一の String 引数を指定する Class getDeclaredConstructor メソッドを使用して、そのようなコンストラクターの Constructor オブジェクトがある場合はそれを取得できます。ただし、たとえば setXXX メソッドを呼び出さないと有用なオブジェクトを取得できないリスクがあり、このアプローチは正しい形式のコンストラクターを持つクラスに限定されます。

おそらくシリアライゼーションとデシリアライゼーションに関連する、より高いレベルの問題を解決しようとしていると思われます。その問題は、現在の問題よりもはるかに簡単に解決できる可能性があります。

于 2012-11-26T16:58:32.423 に答える
0

これが私が思いついた解決策です:

public static Object parse(String value, Class<?> clazz) throws NotSupportedException {
    String canonClassName = clazz.getCanonicalName();

    if (canonClassName.equalsIgnoreCase("java.math.BigDecimal")) {
        return new BigDecimal(value);
    }

    // Add other supported classes here ...

    throw new NotSupportedException("The class [" + canonClassName  + "] is not supported.");
}
于 2012-11-30T10:15:42.907 に答える
0

私はこのスレッドで私の答えを見つけました: How to convert String object to Boolean Object? - 次を使用して、文字列をブール値に解析できます。

Boolean boolean1 = Boolean.valueOf("true");
boolean boolean2 = Boolean.parseBoolean("true");
于 2015-02-02T14:21:41.233 に答える