반사를 사용하지 않고 객체가 배열인지 확인하는 방법은 무엇입니까?


99

리플렉션을 사용하지 않고 객체가 배열인지 Java에서 어떻게 볼 수 있습니까? 리플렉션을 사용하지 않고 모든 항목을 어떻게 반복 할 수 있습니까?

Google GWT를 사용하므로 리플렉션을 사용할 수 없습니다.

반성을 사용하지 않고 다음 메서드를 구현하고 싶습니다.

private boolean isArray(final Object obj) {
  //??..
}

private String toString(final Object arrayObject) {
  //??..
}

BTW : 비 GWT 환경에서 사용할 수 있도록 JavaScript를 사용하고 싶지도 않습니다.

답변:


248

당신이 사용할 수있는 Class.isArray()

public static boolean isArray(Object obj)
{
    return obj!=null && obj.getClass().isArray();
}

이것은 객체 및 기본 유형 배열 모두에서 작동합니다.

toString의 경우 Arrays.toString. 배열 유형을 확인하고 적절한 toString메서드를 호출해야합니다 .


1
을 사용하여 배열 유형을 찾을 수 있다는 점을 추가 할 가치가 있습니다 obj.getClass().getComponentType().
Steve Chambers 19

68

사용할 수 있습니다 instanceof.

JLS 15.20.2 유형 비교 연산자 instanceof

 RelationalExpression:
    RelationalExpression instanceof ReferenceType

런타임에 instanceof연산자 의 결과 trueRelationalExpression 의 값 이 아닌 경우 null이고 참조 는를 발생시키지 않고 ReferenceType 으로 캐스팅 될 수 있습니다 ClassCastException. 그렇지 않으면 결과는 false입니다.

즉, 다음과 같이 할 수 있습니다.

Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"        

당신은 객체가이 있는지 확인해야 할 것 instanceof boolean[], byte[], short[], char[], int[], long[], float[], double[], 또는 Object[], 당신은 모든 배열 유형을 감지합니다.

또한 an int[][]instanceof Object[]이므로 중첩 배열을 처리하려는 방법에 따라 복잡해질 수 있습니다.

를 들어 toString, java.util.ArraystoString(int[])당신이 사용할 수있는 다른 오버로드. 또한이 deepToString(Object[])중첩 배열을 위해.

public String toString(Object arr) {
   if (arr instanceof int[]) {
      return Arrays.toString((int[]) arr);
   } else //...
}

매우 반복적 일 것입니다 (하지만 java.util.Arrays매우 반복적입니다. ). 그러나 그것은 배열이있는 Java에서하는 방식입니다.

또한보십시오


감사합니다. 그렇게 간단하다는 것을 깨닫지 못했습니다. 생각 insstanceof는 T []로 간단하게 사용할 수 없습니다 :(
edbras

2
BTW : 또한 무언가가 배열 Class.isArray () (Arrays.deepToString ()에서 사용됨)인지 발견하는 또 다른 좋은 방법을 발견했습니다.
edbras

@edbras : 네, 스티브 쿠오가 아래에서 말한 것입니다. 내 솔루션은 API 호출 대신 순수한 언어 구조를 사용합니다.
polygenelubricants

잘 작동하지만 instanceof 만 사용하지 않고 getClass를 비교로 사용합니다. 다음과 같습니다. if (array.getClass == int []. class) {Arrays.toString ((int []) array); } 감사합니다 ..
edbras

@edbras : 그게 방법입니다 java.util.Arrays 그렇습니다. 내가 링크 한 코드를 읽고 계셨군요.
polygenelubricants

35

다음 코드를 사용하여 배열의 각 요소에 개별적으로 액세스 할 수 있습니다.

Object o=...;
if ( o.getClass().isArray() ) {
    for(int i=0; i<Array.getLength(o); i++){
        System.out.println(Array.get(o, i));
    }
}

모든 배열에서 작동하므로 기본 배열의 종류를 알 필요가 없습니다.


2
isArray()이미 4 년 전에 게시 된 답변에서 충분히 다루어졌습니다.
Jason C

15
이 답변은 배열의 크기를 가져오고 콘텐츠 유형에 대한 지식없이 요소를 검색하는 방법을 보여주기 때문에 좋습니다. 나는 대부분의 사람들이 이전에 이와 같은 코드를 작성한 적이 없다고 확신합니다.
크리스토퍼 양

@MaartenBodewes- 이 링크 를 사용하여 "반사를 사용하지 않음"이 GWT에 대해 의미하는 바를 결정합니다.
Stephen C

10

기본 유형의 배열간에 또는 기본 유형의 배열과 참조 유형의 배열 간에는 하위 유형 관계가 없습니다. JLS 4.10.3 참조 .

따라서 다음은가 모든 종류obj 의 배열 인지 확인하는 테스트로 올바르지 않습니다 .

// INCORRECT!
public boolean isArray(final Object obj) {
    return obj instanceof Object[];
}

특히, obj기본 요소의 1-D 배열 인 경우 작동하지 않습니다 . (모든 배열 유형이 하위 유형이기 때문에 더 높은 차원의 기본 배열에서 작동합니다.Object 하지만이 경우에는 문제가됩니다.)

Google GWT를 사용하므로 리플렉션을 사용할 수 없습니다.

( isArray질문 의 배열 부분에 대한) 최상의 솔루션 은 "반사 사용"으로 간주되는 항목에 따라 다릅니다.

  • GWT에서 호출 obj.getClass().isArray()은 Reflection 1 을 사용하는 것으로 간주되지 않으므로 이것이 최상의 솔루션입니다.

  • 그렇지 않으면 객체에 배열 유형이 있는지 확인하는 가장 좋은 방법은 일련의 instanceof표현식 을 사용하는 것입니다 .

    public boolean isArray(final Object obj) {
        return obj instanceof Object[] || obj instanceof boolean[] ||
           obj instanceof byte[] || obj instanceof short[] ||
           obj instanceof char[] || obj instanceof int[] ||
           obj instanceof long[] || obj instanceof float[] ||
           obj instanceof double[];
    }
  • 다음과 같이 객체의 클래스 이름을 엉망으로 만들 수도 있지만 호출 obj.getClass()은 반사에 가깝습니다.

    public boolean isArray(final Object obj) {
        return obj.getClass().toString().charAt(0) == '[';
    }

1-보다 정확하게 Class.isArray이 페이지 에서 GWT에서 지원 하는 방법으로 나열됩니다 .


0

유틸리티 클래스를 만들어 클래스가 Collection , Map 또는 Array를 나타내는 지 확인할 수 있습니다.

  public static boolean isCollection(Class<?> rawPropertyType) {
        return Collection.class.isAssignableFrom(rawPropertyType) || 
               Map.class.isAssignableFrom(rawPropertyType) || 
               rawPropertyType.isArray();
 }

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