자바 배열 반영 : isArray와 instanceof


177

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

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

if(obj instanceof Object[]) {}

?

답변:


203

대부분의 경우 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됩니다.


7
네,하지만 얼마나 큰 차이가 있습니까? 그것은 저에게 마이크로 최적화처럼 들립니다.
Michael Myers

2
당신이 주장하는 경우 @Dims은 obj instanceof int[]수율 false당신이를 할당 int[]에를 obj, 당신은 착각이다.
erickson

4
죄송하지만 지금은 그 의미 obj instanceof Object[]수율을 false경우 Object obj = new int[7].
Dims

3
Java에서 기본 데이터 유형은 객체가 아니며 확장되지 않으므로 java.lang.Object의미가 있습니다. 그러나 instanceof여전히 원시 배열을 테스트하는 데 사용할 수 있습니다.
erickson

4
-1 : 일반적으로 기본 배열 배열 이므로 호출을 isArray()사용해야합니다. 객체 배열 만 갖는 매우 일반적인 특수한 경우에는 instanceof고성능 대안을 제공합니다.
Sam Harwell


8

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


4

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

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


10
통계, 사례 연구 또는 연결할 수있는 다른 증거가 있습니까?
David Citron

4

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

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

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


말이되지 않습니다. isArray하는 방법입니다 Class하지, Type물론 지금의, GenericArrayTypeImpl그 방법이 없습니다. 그리고 getClassnon-을 반환 할 수 없으므로 Class Type모든 ( Type가) 라고 가정하는 것처럼 당신 (또는 Groovy ??)은 이것을 얻지 못했을 것 Class입니다.
kaqqao

3

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

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


2

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


어, "instanceof"는 일종의 반성 (또는 적어도 내성)이지만, 나는 당신의 요점을 얻습니다.
David Citron

또한 일반적으로 느립니다.
Mad Physicist

0

두 가지 사이에서 찾을 수있는 행동에는 차이가 없습니다 (명백한 null이 아닌 경우). 어떤 버전을 선호하는지에 관해서는 두 번째로 갈 것입니다. Java에서이를 수행하는 표준 방법입니다.

코드 리더가 혼란 스러울 경우 ( String[] instanceof Object[]참이 되었기 때문에 ) 코드 검토자가 계속 묻는다면 첫 번째 코드를 더 명확하게 사용하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.