2009-04-19 5 views
121

이것은 아마도 이전에 요청 받았지만 빠른 검색은 C#과 같은 질문만을 제기했습니다. See here.객체가 인터페이스를 구현하는지 테스트합니다.

기본적으로 주어진 개체가 주어진 인터페이스를 구현하는지 확인하는 것이 좋습니다.

일종의 솔루션을 찾았지만이 코드는 if 문이나 case 문에서 자주 사용하기에는 편안하지 않으며 Java에 기본 제공되는 솔루션이 없는지 궁금합니다.

public static Boolean implementsInterface(Object object, Class interf){ 
    for (Class c : object.getClass().getInterfaces()) { 
     if (c.equals(interf)) { 
      return true; 
     } 
    } 
    return false; 
} 


편집 : 좋아, 귀하의 답변을 주셔서 감사합니다. 특히 Damien Pollet과 Noldorin에게 당신은 내 디자인을 다시 생각하게 만들었으므로 더 이상 인터페이스를 테스트하지 않았습니다.

+3

를 호출하기 전에! null의 경우 확인 (또는 확인 자바가 C ​​# "as"연산자와 유사한 것을 가지고 있다면 널 결과도)? 저는 Java가 아닌 C# 코더입니다. 그래서 저는이 같은 접근법이 모든 OO 언어에서 가능할 것이라고 생각하지만, 주로 여기에서 추측하고 있습니다. – Noldorin

+0

예! 당신은 환영합니다 :) –

+0

퍼포먼스에 신경 쓸 필요가없는 경우에만 Throwing Exception을 사용하는 것이 좋습니다. – Rafa

답변

159

instanceof 운영자가 NullPointerException 안전한 방법으로 작업을 수행합니다. 예 :

if ("" instanceof java.io.Serializable) { 
    // it's true 
} 

이 true로 설정됩니다. 이후 :

if (null instanceof AnyType) { 
    // never reached 
} 

거짓 산출의 instanceof 운영자가 null의 안전은 (당신이 게시 코드가 아닌)입니다. instanceof를

내가 instanceof 선호 Class#isInstance(Object)

+4

instanceof는 클래스 리터럴에서만 작동합니다. 따라서 OP의 경우에는 사용할 수 없습니다 – LordOfThePigs

+0

확실히 컴파일 타임에 안전합니다. 그것은 내장 된 방법이며 그것은 질문 (imho)의 논증입니다 – dfa

+0

@LordOfThePigs 그렇지 않습니다. 인터페이스가 구현되었는지 검사합니다. – NimChimpsky

40

이 수행해야합니다

예를 들어
public static boolean implementsInterface(Object object, Class interf){ 
    return interf.isInstance(object); 
} 

,

java.io.Serializable.class.isInstance("a test string") 

true로 평가합니다.

+1

+1 this - object가 null 인 경우 실패하지 않습니다. – msangel

3

하는 것은 쉬웠다 그 :

interf.isInstance(object) 
7

에 내장, 컴파일시 안전한 대안입니다 :

if (obj instanceof SomeType) { ... } 

훨씬 더 많이 읽을 수 SomeType.isInstance(obj)

+3

'if (obj instanceof SomeType) {...}'이 정적 인 것을 기억하십시오 즉, 런타임에 변경할 수 없음) 'SomeType.isInstance (obj)'는 동적입니다. –

2

보다 당신이 만약 인터페이스를 테스트하고 싶습니다.

public List<myType> getElement(Class<?> clazz) { 
    List<myType> els = new ArrayList<myType>(); 
    for (myType e: this.elements.values()){ 
     if (clazz.isAssignableFrom(e.getClass()) == true){ 
      els.add(e); 
     } 
    } 
    return els; 

clazz는 인터페이스이며 myType은 사용자가 정의한 Tyoe로 여러 인터페이스를 구현할 수 있습니다. 필요한 인터페이스가 인터페이스에 포함되는 경우이 코드를 사용하면 아파치 평민 - 랭 ArrayUtils로 정의 된 인터페이스

0

를 구현하는 유형 만 얻을, 당신은 내가이 문제 오늘 밤 있었다

public static Boolean implementsInterface(Object object, Class interf){ 
    return ArrayUtils.contains(object.getClass().getInterfaces(), interf); 
} 
1

객체의 참조 안드로이드와 함께 그리고 javadoc 솔루션을 살펴본 후에 나는 javadoc 설명보다 조금 더 많은 것을 필요로하는 나 같은 사람들을 위해이 실제 작업 솔루션을 생각해 냈다.

다음은 android java를 사용하는 실제 인터페이스가있는 작동 예제입니다. AboutDialogListener 필드를 캐스팅하기 전에 AboutDialogListener 인터페이스 을 구현하여 호출 한 활동을 확인합니다.

public class About extends DialogFragment implements OnClickListener, 
    OnCheckedChangeListener { 

public static final String FIRST_RUN_ABOUT = "com.gosylvester.bestrides.firstrunabout"; 


public interface AboutDialogListener { 
    void onFinishEditDialog(Boolean _Checked); 
} 

private AboutDialogListener adl; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    Activity a = this.getActivity(); 
    if (AboutDialogListener.class.isInstance(a)) { 
     adl = (AboutDialogListener) a; 
     } 
} 

은 ... 나중에 내가 필드 ADL은 그냥 캐스팅을 시도하고 하나가 발생하면 예외를 잡을 수 없습니다 인터페이스

@Override 
public void onStop() { 
    super.onStop(); 
    sharedPref.edit().putBoolean(About.FIRST_RUN_ABOUT, _Checked).commit(); 
    // if there is an interface call it. 
    if (adl != null) { 
     adl.onFinishEditDialog(is_Checked()); 
    } 
} 
관련 문제