Por lo que vale, la mayoría de los lenguajes de scripting (como Perl) y los lenguajes en tiempo de compilación no estáticos (como Pick) admiten conversiones automáticas de cadenas dinámicas en tiempo de ejecución a objetos (relativamente arbitrarios). Esto también se PUEDE lograr en Java sin perder la seguridad de tipos y las cosas buenas que proporcionan los lenguajes de tipo estático SIN los desagradables efectos secundarios de algunos de los otros lenguajes que hacen cosas malas con la conversión dinámica. Un ejemplo de Perl que hace algunas matemáticas cuestionables:
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
En Java, esto se logra mejor (en mi humilde opinión) utilizando un método que llamo "cross-casting". Con la transmisión cruzada, la reflexión se usa en una caché de constructores y métodos con carga diferida que se descubren dinámicamente a través del siguiente método estático:
Object fromString (String value, Class targetClass)
Desafortunadamente, ningún método Java integrado como Class.cast () hará esto para String to BigDecimal o String to Integer o cualquier otra conversión donde no haya una jerarquía de clases de soporte. Por mi parte, el punto es proporcionar una forma completamente dinámica de lograr esto, para lo cual no creo que la referencia previa sea el enfoque correcto, tener que codificar cada conversión. En pocas palabras, la implementación es solo para lanzar desde una cadena si es legal / posible.
Entonces, la solución es una simple reflexión buscando Miembros públicos de:
STRING_CLASS_ARRAY = (nueva Clase [] {String.class});
a) Miembro miembro = targetClass.getMethod (method.getName (), STRING_CLASS_ARRAY); b) Miembro miembro = targetClass.getConstructor (STRING_CLASS_ARRAY);
Encontrará que todas las primitivas (Integer, Long, etc.) y todos los conceptos básicos (BigInteger, BigDecimal, etc.) e incluso java.regex.Pattern están cubiertos a través de este enfoque. He utilizado esto con un éxito significativo en proyectos de producción donde hay una gran cantidad de entradas de valor de cadena arbitrarias donde se necesitaba una verificación más estricta. En este enfoque, si no hay un método o cuando se invoca el método, se lanza una excepción (porque es un valor ilegal, como una entrada no numérica para un BigDecimal o una expresión regular ilegal para un patrón), eso proporciona la verificación específica para la lógica inherente de la clase de destino.
Esto tiene algunas desventajas:
1) Necesitas entender bien la reflexión (esto es un poco complicado y no para principiantes). 2) Algunas de las clases de Java y, de hecho, las bibliotecas de terceros (sorpresa) no están codificadas correctamente. Es decir, hay métodos que toman un único argumento de cadena como entrada y devuelven una instancia de la clase de destino, pero no es lo que piensas ... Considere la clase Integer:
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
El método anterior realmente no tiene nada que ver con los enteros como objetos que envuelven enteros primitivos. Reflection encontrará esto como un posible candidato para crear un entero a partir de una cadena de forma incorrecta frente a los miembros decodificación, valor y constructor, que son todos adecuados para la mayoría de las conversiones de cadenas arbitrarias en las que realmente no tiene control sobre sus datos de entrada, pero solo desea saber si es posible un entero.
Para remediar lo anterior, buscar métodos que arrojen Excepciones es un buen comienzo porque los valores de entrada inválidos que crean instancias de tales objetos deben una Excepción. Desafortunadamente, las implementaciones varían en cuanto a si las Excepciones se declaran como verificadas o no. Integer.valueOf (String) arroja una NumberFormatException marcada, por ejemplo, pero las excepciones Pattern.compile () no se encuentran durante las búsquedas de reflejos. Una vez más, no es una falla de este enfoque dinámico de "conversión cruzada", creo que es una implementación muy no estándar para las declaraciones de excepción en los métodos de creación de objetos.
Si alguien desea obtener más detalles sobre cómo se implementó lo anterior, hágamelo saber, pero creo que esta solución es mucho más flexible / extensible y con menos código sin perder las partes buenas de seguridad de tipos. Por supuesto, siempre es mejor "conocer sus datos" pero, como muchos de nosotros descubrimos, a veces solo somos destinatarios de contenido no administrado y tenemos que hacer todo lo posible para usarlo correctamente.
Salud.