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