개체가 매개 변수 유형의 인스턴스인지 테스트


82

객체가 제네릭 유형의 인스턴스인지 확인하는 방법이 있습니까?

public <T> test(Object obj) {
    if (obj instanceof T) {
        ...
    }
}

그것은 분명히 작동하지 않습니다. 대안이 있습니까? Java 리플렉션을 사용하여 클래스를 인스턴스화 한 다음 generic 형식인지 확인하고 싶습니다 T.

답변:


125

이 검사를 수행 할 수있는 유일한 방법 Class은 유형을 나타내는 객체가있는 경우입니다.

Class<T> type; //maybe passed into the method
if ( type.isInstance(obj) ) {
   //...
}

type메소드 매개 변수 로 가져 오지 않으려면 초기화 할 수 있습니다.Class type = ((T) new Object()).getClass();
JordiVilaplana

9
@JordiVilaplana 맞지 않습니다. java.lang.Object를 클래스로 제공합니다. 이 체크 아웃 ideone.com/bxt9Jq
스리랑카 Harsha에 Chilakapati

3
사용 :Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Ton Snoei

20

Mark Peters의 샘플을 확장하려면 다음과 같은 작업을 수행해야합니다.

Class<T> type; //maybe passed to the method
if ( type.isInstance(obj) ) {
   T t = type.cast(obj);
   // ...
}

11

Mark Peters가 언급 한대로 클래스 유형을 매개 변수로 전달하지 않으려면 다음 코드를 사용할 수 있습니다. David O'Meara에 대한 명성.

  Class<T> type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
                  .getActualTypeArguments()[0];
  if (type.isInstance(obj)) {
      ...
  }

5
그것은 준다Type safety: Unchecked cast from Type to Class<T>
Marco Sulla

5

이것을 시도해 볼 수 있습니다.

// Cast your object to the generic type.
T data = null;
try {
    data = (T) obj;
} catch (ClassCastException cce) {
    // Log the error.
}

// Check if the cast completed successfully.
if(data != null) {
    // whatever....
}

7
작동하지 않습니다! 모든 유형에 대해 캐스트가 성공합니다 . 이것이 "Unchecked cast"컴파일 경고를 제공하는 이유입니다.
Lii

3

유형 T을 매개 변수화하는 데 유형 이 사용되는 위치에 제한을 두는 것이 더 합리적 Class입니다. 대신 같은 것을 사용하는,의 유형을 통과하면 Class<?>, 당신은 사용해야합니다 Class<? extends T>.


1
런타임에 정확한 T 유형을 알고 싶다면 호출자가 Class <?가 아닌 Class <T>를 전달하도록 요구하는 것이 중요합니다. T>를 확장합니다. 예를 들어 Puce의 코드는 Class <? T>를 확장합니다.
Theodore Murdock 2014 년

1

이것은 T 유형의 객체가있는 경우에만 (부분적으로) 작동합니다. 그러면 해당 객체의 클래스를 가져 와서 해당 객체 java.lang.Class<T>와 동일한 지 확인 하고 찾을 수 있습니다.

그러나 이것은 우리가 장르가있는 바로 그 이유와 상반된다는 점에 유의하십시오. 제네릭 유형을 사용하는 것은 그것이 실제로 어떤 유형인지 (지정 될 수있는 상한 및 하한까지) 상관하지 않는다는 것을 말하는 방법입니다.


null이 아닌 T 인스턴스에 대한 .getClass () 호출에서 반환 된 Class <?>가 Class <T>라는 보장은 없습니다. 당신이 보장 할 수있는 최선은 그것이 Class <? T>를 확장합니다.
Theodore Murdock 2014 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.