ほとんどのスクリプト言語(Perlなど)と非静的コンパイル時言語(Pickなど)は、自動実行時動的文字列から(比較的任意の)オブジェクトへの変換をサポートしています。これは、型の安全性を失うことなくJavaでも実現でき、静的に型付けされた言語は、動的キャストで悪事を行う他の言語の厄介な副作用なしに提供します。疑わしい計算を行うPerlの例:
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
Javaでは、これは私が「クロスキャスティング」と呼ぶメソッドを使用することでよりよく達成されます(IMHO)。クロスキャスティングでは、リフレクションは、次の静的メソッドを介して動的に検出されるコンストラクターとメソッドの遅延ロードされたキャッシュで使用されます。
Object fromString (String value, Class targetClass)
残念ながら、Class.cast()などの組み込みJavaメソッドは、StringからBigDecimal、StringからInteger、またはサポートするクラス階層がないその他の変換に対してこれを実行しません。私の側では、これを達成するための完全に動的な方法を提供することが重要です-事前の参照が正しいアプローチであるとは思わない-すべての変換をコーディングする必要があります。簡単に言えば、実装は、合法/可能であれば、文字列からキャストするだけです。
したがって、解決策は、次のいずれかのパブリックメンバーを探す単純なリフレクションです。
STRING_CLASS_ARRAY =(new Class [] {String.class});
a)メンバーmember = targetClass.getMethod(method.getName()、STRING_CLASS_ARRAY); b)メンバーmember = targetClass.getConstructor(STRING_CLASS_ARRAY);
すべてのプリミティブ(Integer、Longなど)とすべての基本(BigInteger、BigDecimalなど)、さらにはjava.regex.Patternもすべてこのアプローチでカバーされていることがわかります。私はこれを使用して、より厳密なチェックが必要な任意の文字列値の入力が大量にある本番プロジェクトで大きな成功を収めました。このアプローチでは、メソッドがない場合、またはメソッドが呼び出されたときに例外がスローされます(BigDecimalへの非数値入力やパターンの不正な正規表現などの不正な値であるため)。これにより、に固有のチェックが提供されます。ターゲットクラス固有のロジック。
これにはいくつかの欠点があります。
1)反射をよく理解する必要があります(これは少し複雑で、初心者向けではありません)。2)一部のJavaクラスと実際にサードパーティのライブラリは(驚いたことに)適切にコーディングされていません。つまり、単一の文字列引数を入力として受け取り、ターゲットクラスのインスタンスを返すメソッドがありますが、それはあなたが考えていることではありません... Integerクラスを考えてみましょう。
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
上記のメソッドは、プリミティブintをラップするオブジェクトとしての整数とは実際には何の関係もありません。Reflectionは、これを、文字列から整数を誤って作成する可能性のある候補として、デコード、valueof、およびコンストラクターのメンバーと比較して見つけます。これらはすべて、入力データを実際に制御することはできないが、それが整数である可能性があるかどうかを知っています。
上記を修正するには、例外をスローするメソッドを探すことから始めるとよいでしょう。そのようなオブジェクトのインスタンスを作成する無効な入力値は例外をスローするはずだからです。残念ながら、例外がチェック済みとして宣言されているかどうかに関しては、実装が異なります。たとえば、Integer.valueOf(String)はチェックされたNumberFormatExceptionをスローしますが、リフレクションルックアップ中にPattern.compile()例外は見つかりません。繰り返しになりますが、この動的な「クロスキャスティング」アプローチの失敗ではなく、オブジェクト作成メソッドの例外宣言の非常に非標準的な実装だと思います。
上記の実装方法の詳細が必要な場合はお知らせください。ただし、このソリューションは、型安全性の優れた部分を失うことなく、はるかに柔軟で拡張性があり、コードが少ないと思います。もちろん、「あなたのデータを知る」ことは常に最善ですが、私たちの多くが見つけるように、私たちは時々管理されていないコンテンツの受信者であり、それを適切に使用するために最善を尽くさなければなりません。
乾杯。