Pelo que vale a pena, a maioria das linguagens de script (como Perl) e linguagens de tempo de compilação não estática (como Pick) oferecem suporte a conversões de objetos dinâmicos em tempo de execução automático para (relativamente arbitrários). Isso PODE ser realizado em Java também sem perder a segurança de tipo e as boas linguagens tipadas estaticamente fornecem SEM os efeitos colaterais desagradáveis de algumas das outras linguagens que fazem coisas más com a conversão dinâmica. Um exemplo Perl que faz algumas contas questionáveis:
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
Em Java, isso é melhor realizado (IMHO) usando um método que chamo de "cross-casting". Com a conversão cruzada, a reflexão é usada em um cache lento de construtores e métodos que são descobertos dinamicamente por meio do seguinte método estático:
Object fromString (String value, Class targetClass)
Infelizmente, nenhum método Java integrado, como Class.cast () fará isso para String para BigDecimal ou String para Integer ou qualquer outra conversão onde não há hierarquia de classes de suporte. De minha parte, o objetivo é fornecer uma maneira totalmente dinâmica de conseguir isso - para a qual não acho que a referência anterior seja a abordagem certa - ter que codificar cada conversão. Simplificando, a implementação é apenas para cast-from-string se for legal / possível.
Portanto, a solução é a simples reflexão em busca de membros públicos de:
STRING_CLASS_ARRAY = (nova classe [] {String.class});
a) Membro membro = targetClass.getMethod (method.getName (), STRING_CLASS_ARRAY); b) Membro membro = targetClass.getConstructor (STRING_CLASS_ARRAY);
Você descobrirá que todos os primitivos (Integer, Long, etc) e todos os básicos (BigInteger, BigDecimal, etc) e até mesmo java.regex.Pattern são cobertos por essa abordagem. Eu usei isso com sucesso significativo em projetos de produção onde há uma grande quantidade de entradas de valor de String arbitrárias onde alguma verificação mais estrita era necessária. Nesta abordagem, se não houver método ou quando o método é invocado, uma exceção é lançada (porque é um valor ilegal, como uma entrada não numérica para um BigDecimal ou RegEx ilegal para um Padrão), que fornece a verificação específica para a lógica inerente da classe de destino.
Existem algumas desvantagens para isso:
1) Você precisa entender bem a reflexão (isso é um pouco complicado e não para novatos). 2) Algumas das classes Java e, de fato, bibliotecas de terceiros (surpresa) não são codificadas corretamente. Ou seja, existem métodos que recebem um único argumento de string como entrada e retornam uma instância da classe de destino, mas não é o que você pensa ... Considere a classe Integer:
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
O método acima realmente não tem nada a ver com inteiros como objetos que envolvem inteiros primitivos. O Reflection descobrirá que isso é um possível candidato para a criação incorreta de um inteiro a partir de uma string em comparação com os membros decodificadores, valueof e constructor - que são adequados para a maioria das conversões de strings arbitrárias em que você realmente não tem controle sobre seus dados de entrada, mas apenas deseja saber se é possível um Inteiro.
Para remediar o acima, procurar métodos que lançam Exceptions é um bom começo porque valores de entrada inválidos que criam instâncias de tais objetos devem lançar uma Exception. Infelizmente, as implementações variam quanto ao fato de as exceções serem declaradas como verificadas ou não. Integer.valueOf (String) lança uma NumberFormatException marcada, por exemplo, mas as exceções Pattern.compile () não são encontradas durante as pesquisas de reflexão. Novamente, não é uma falha dessa abordagem dinâmica de "cross-casting", eu acho que é uma implementação muito diferente do padrão para declarações de exceção em métodos de criação de objeto.
Se alguém quiser mais detalhes sobre como o acima foi implementado, me avise, mas eu acho que essa solução é muito mais flexível / extensível e com menos código sem perder as partes boas da segurança de tipo. Obviamente, é sempre melhor "conhecer seus dados", mas, como muitos de nós descobrimos, às vezes somos apenas destinatários de conteúdo não gerenciado e temos que fazer o melhor que podemos para usá-lo adequadamente.
Felicidades.