그만한 가치가있는 대부분의 스크립팅 언어 (예 : Perl) 및 비 정적 컴파일 시간 언어 (예 : Pick)는 (상대적으로 임의의) 객체 변환에 대한 자동 런타임 동적 문자열을 지원합니다. 이것은 유형 안전성을 잃지 않고 Java에서도 수행 할 수 있으며 정적으로 유형화 된 언어는 동적 캐스팅으로 악한 일을하는 다른 언어의 불쾌한 부작용없이 제공합니다. 의심스러운 수학을 수행하는 Perl 예제 :
print ++($foo = '99'); # prints '100'
print ++($foo = 'a0'); # prints 'a1'
Java에서는 "cross-casting"이라고 부르는 방법을 사용하여 더 잘 수행됩니다 (IMHO). 크로스 캐스팅을 통해 리플렉션은 다음 정적 메서드를 통해 동적으로 검색되는 생성자 및 메서드의 지연로드 캐시에서 사용됩니다.
Object fromString (String value, Class targetClass)
불행히도 Class.cast ()와 같은 내장 Java 메소드는 String에서 BigDecimal로 또는 String에서 Integer로 또는 지원하는 클래스 계층 구조가없는 다른 변환에 대해이를 수행하지 않습니다. 필자의 경우 요점은이를 달성하기위한 완전히 동적 인 방법을 제공하는 것입니다. 이전 참조가 올바른 접근 방식이 아니라고 생각하므로 모든 변환을 코딩해야합니다. 간단히 말해서, 구현은 합법적이거나 가능한 경우 문자열에서 캐스트하는 것입니다.
따라서 해결책은 다음 중 하나의 공개 구성원을 찾는 간단한 반영입니다.
STRING_CLASS_ARRAY = (새 클래스 [] {String.class});
a) 멤버 멤버 = targetClass.getMethod (method.getName (), STRING_CLASS_ARRAY); b) 멤버 멤버 = targetClass.getConstructor (STRING_CLASS_ARRAY);
모든 프리미티브 (Integer, Long 등)와 모든 기본 (BigInteger, BigDecimal 등) 및 심지어 java.regex.Pattern까지 모두이 접근 방식을 통해 다룹니다. 나는 더 엄격한 검사가 필요한 엄청난 양의 임의의 문자열 값 입력이있는 프로덕션 프로젝트에서 상당한 성공을 거두었습니다. 이 접근 방식에서는 메서드가 없거나 메서드가 호출 될 때 예외가 throw됩니다 (BigDecimal에 대한 숫자가 아닌 입력 또는 패턴에 대한 잘못된 RegEx와 같은 잘못된 값이기 때문). 대상 클래스 고유 논리.
이에 대한 몇 가지 단점이 있습니다.
1) 성찰을 잘 이해해야합니다 (초보자가 아니라 조금 복잡합니다). 2) 일부 Java 클래스와 실제로 타사 라이브러리는 (놀랍게도) 제대로 코딩되지 않았습니다. 즉, 단일 문자열 인수를 입력으로 사용하고 대상 클래스의 인스턴스를 반환하는 메서드가 있지만 생각하는 것과 다릅니다 ... Integer 클래스를 고려하십시오.
static Integer getInteger(String nm)
Determines the integer value of the system property with the specified name.
위의 방법은 실제로 기본 int를 래핑하는 객체로서 Integer와 관련이 없습니다. Reflection은 이것을 디코딩, 값 및 생성자 멤버와 비교하여 문자열에서 정수를 잘못 생성 할 수있는 가능한 후보로 간주합니다. 이는 모두 입력 데이터를 제어 할 수 없지만 원하는 경우 대부분의 임의 문자열 변환에 적합합니다. Integer가 가능한지 알고 있습니다.
위의 문제를 해결하려면 예외를 발생시키는 메서드를 찾는 것이 좋습니다. 이러한 개체의 인스턴스를 만드는 잘못된 입력 값 은 예외를 발생 시켜야 하기 때문 입니다. 불행히도 구현은 예외가 확인 된 것으로 선언되었는지 여부에 따라 다릅니다. 예를 들어 Integer.valueOf (String)는 확인 된 NumberFormatException을 throw하지만 리플렉션 조회 중에 Pattern.compile () 예외를 찾을 수 없습니다. 다시 말하지만,이 동적 "크로스 캐스팅"접근 방식의 실패가 아니라 객체 생성 메서드에서 예외 선언을위한 매우 비표준 구현이라고 생각합니다.
위의 구현 방법에 대한 자세한 내용을 원하는 사람이 있으면 알려주십시오. 그러나이 솔루션은 유형 안전성의 좋은 부분을 잃지 않고 코드가 적고 훨씬 유연하고 확장 가능하다고 생각합니다. 물론 "귀하의 데이터를 아는"것이 항상 최선이지만, 많은 사람들이 알고 있듯이 우리는 관리되지 않는 콘텐츠의 수신자 일 뿐이며 적절하게 사용하기 위해 최선을 다해야합니다.
건배.