Как бы то ни было, большинство языков сценариев (например, Perl) и нестатических языков времени компиляции (например, Pick) поддерживают автоматические преобразования динамической строки во время выполнения в (относительно произвольные) преобразования объектов. Это МОЖЕТ быть достигнуто и в Java без потери безопасности типов, и хорошие вещи, которые статически типизированные языки обеспечивают БЕЗ неприятных побочных эффектов некоторых других языков, которые делают злые вещи с динамическим преобразованием. Пример Perl, который выполняет некоторые сомнительные вычисления:
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
В Java это лучше сделать (IMHO) с помощью метода, который я называю «перекрестное приведение». При перекрестном преобразовании отражение используется в кэше с отложенной загрузкой конструкторов и методов, которые обнаруживаются динамически с помощью следующего статического метода:
Object fromString (String value, Class targetClass)
К сожалению, никакие встроенные методы Java, такие как Class.cast (), не сделают этого для String to BigDecimal или String to Integer или любого другого преобразования, в котором нет поддерживающей иерархии классов. С моей стороны, цель состоит в том, чтобы обеспечить полностью динамический способ достижения этого - для чего я не думаю, что предыдущая ссылка - правильный подход - необходимость кодировать каждое преобразование. Проще говоря, реализация - это просто приведение из строки, если это допустимо / возможно.
Таким образом, решение - это простое отражение, ищущее публичных членов либо:
STRING_CLASS_ARRAY = (новый класс [] {String.class});
а) Член-член = targetClass.getMethod (method.getName (), STRING_CLASS_ARRAY); б) Член-член = targetClass.getConstructor (STRING_CLASS_ARRAY);
Вы обнаружите, что все примитивы (Integer, Long и т.д.) и все основы (BigInteger, BigDecimal и т.д.) и даже java.regex.Pattern охватываются этим подходом. Я использовал это с большим успехом в производственных проектах, где существует огромное количество произвольных входных значений String, где требовалась более строгая проверка. В этом подходе, если нет метода или когда метод вызывается, генерируется исключение (потому что это недопустимое значение, такое как нечисловой ввод в BigDecimal или недопустимое регулярное выражение для шаблона), которое обеспечивает проверку, специфичную для внутренняя логика целевого класса.
У этого есть некоторые недостатки:
1) Вам нужно хорошо понимать рефлексию (это немного сложно и не для новичков). 2) Некоторые классы Java и, действительно, сторонние библиотеки (сюрприз) неправильно закодированы. То есть есть методы, которые принимают на вход единственный строковый аргумент и возвращают экземпляр целевого класса, но это не то, что вы думаете ... Рассмотрим класс Integer:
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
Вышеупомянутый метод действительно не имеет ничего общего с целыми числами как объектами, обертывающими примитивы целыми числами. Reflection обнаружит, что это возможный кандидат на создание целого числа из String неправильно по сравнению с членами decode, valueof и constructor, которые подходят для большинства произвольных преобразований String, когда вы действительно не контролируете свои входные данные, а просто хотите знать, возможно ли это целое число.
Чтобы исправить это, поиск методов, которые генерируют исключения, является хорошим началом, поскольку недопустимые входные значения, которые создают экземпляры таких объектов, должны вызывать исключение. К сожалению, реализации различаются в зависимости от того, объявляются ли исключения как отмеченные или нет. Integer.valueOf (String), например, выдает проверенное NumberFormatException, но исключения Pattern.compile () не обнаруживаются во время поиска отражения. Опять же, это не провал этого динамического подхода «перекрестного преобразования», я думаю, что это очень нестандартная реализация для объявлений исключений в методах создания объектов.
Если кто-то захочет получить более подробную информацию о том, как было реализовано вышеупомянутое, дайте мне знать, но я думаю, что это решение намного более гибкое / расширяемое и с меньшим количеством кода без потери хороших частей безопасности типов. Конечно, всегда лучше «знать свои данные», но, как многие из нас обнаруживают, иногда мы являемся только получателями неуправляемого контента и должны делать все возможное, чтобы использовать его должным образом.
Ура.