[java] 자바 배열 반영 : isArray와 instanceof

다음을 사용하는 것 사이에 선호도 또는 동작 차이가 있습니까?

if(obj.getClass().isArray()) {}

if(obj instanceof Object[]) {}

?



답변

대부분의 경우 instanceof연산자를 사용하여 객체가 배열인지 테스트 해야합니다 .

일반적으로 컴파일 타임에 알려진 특정 유형으로 다운 캐스팅하기 전에 객체 유형을 테스트합니다. 예를 들어, a Integer[]또는 a와 함께 사용할 수있는 코드를 작성했을 수 있습니다 int[]. 다음을 사용하여 캐스트를 보호하고 싶습니다 instanceof.

if (obj instanceof Integer[]) {
    Integer[] array = (Integer[]) obj;
    /* Use the boxed array */
} else if (obj instanceof int[]) {
    int[] array = (int[]) obj;
    /* Use the primitive array */
} else ...

JVM 레벨에서 instanceof연산자는 특정 “instanceof” 바이트 코드로 변환 되며 대부분의 JVM 구현에 최적화됩니다.

드문 경우이지만 반사를 사용하여 알 수없는 유형의 객체 그래프를 통과 할 수 있습니다. 이와 같은 경우 isArray()컴파일시 구성 요소 유형을 모르기 때문에이 메소드가 도움이 될 수 있습니다. 예를 들어 일종의 직렬화 메커니즘을 구현하고 유형에 관계없이 배열의 각 구성 요소를 동일한 직렬화 방법으로 전달할 수 있습니다.

널 (null) 참조 및 기본 배열에 대한 참조의 두 가지 특수한 경우가 있습니다.

null 참조는 instanceof결과를 초래 false하지만 isArraythrow는 a를 발생 NullPointerException시킵니다.

기본 배열에 적용되는 경우, 오른쪽 피연산자의 구성 요소 유형이 구성 요소 유형과 정확히 일치하지 않는 한 instanceof수율을 나타 false냅니다. 반대로 모든 구성 요소 유형에 대해 isArray()반환 true됩니다.


답변

후자의 경우, obj가 null이면 NullPointerException이 아니라 false입니다.


답변

say obj유형 이면 int[]배열이 Class있지만의 인스턴스는 아닙니다 Object[]. 무엇을하고 싶습니까 obj? 당신이 그것을 던질 예정이라면,로 가십시오 instanceof. 리플렉션을 사용하려면을 사용하십시오 .getClass().isArray().


답변

getClass().isArray() Sun Java 5 또는 6 JRE에서 IBM보다 훨씬 느립니다.

clazz.getName().charAt(0) == '['Sun JVM에서 사용하는 것이 훨씬 빠릅니다.


답변

최근에 Groovy 애플리케이션을 JDK 5에서 JDK 6으로 업그레이드하는 데 문제가 발생 isArray()했습니다. JDK6에서 사용에 실패했습니다.

MissingMethodException:
No signature of sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl.isArray() ...

instanceof Object[]이 문제 를 해결하기 위해 변경 .


답변

Java 배열 반영은 “인스턴스”를 수행 할 수있는 클래스 인스턴스가없는 경우를위한 것입니다. 예를 들어, JPA처럼 클래스의 새로운 인스턴스에 값을 주입하는 일종의 주입 프레임 워크를 작성하는 경우 isArray () 기능을 사용해야합니다.

나는 12 월 초에 이것을 블로그에 올렸다.
http://blog.adamsbros.org/2010/12/08/java-array-reflection/


답변

반사 형 솔루션과 비반 사형 솔루션 중 하나를 선택할 수있는 경우 반사 형 솔루션 (클래스 객체 포함)을 선택하지 마십시오. 그것이 “잘못”이거나 다른 것이 아니라, 반사와 관련된 것은 일반적으로 덜 명확하고 덜 명확합니다.