자바 : Class.isInstance 대 Class.isAssignableFrom


232

하자 clazz일부가 될 Classobj일부를 수 Object.

입니다

clazz.isAssignableFrom(obj.getClass())

항상 같은

clazz.isInstance(obj)

?

그렇지 않은 경우 차이점은 무엇입니까?


26
obj == null이면 두 번째는 false를 반환하고 첫 번째는 false를 반환하지 않습니다. ;)
Peter Lawrey

21
@PeterLawrey, 첫 번째는 NullPointerExceptionif 을 던집니다 obj == null.
ryvantage

: 샘플 몇 가지 대답 리어에서 찾을 수 mytechnotes.biz/2012/07/...
Paramesh Korrakuti

4
독자들에게 : 당신은 결코 탈출 할 수없는 깊고 어두운 블랙홀에 들어 가려고합니다. 차이점은 끝이 없습니다. 지금 포기 당신이 아직도 할 수있는 동안 : stackoverflow.com/q/496928/1599699
앤드류

@ParameshKorrakuti 도메인 이름이 tshikatshikaaa.blogspot.com/2012/07/…
Jérôme Verstrynge

답변:


222

clazz.isAssignableFrom(Foo.class)clazz객체가 나타내는 클래스가의 수퍼 클래스 또는 수퍼 인터페이스 일 때마다 true 입니다 Foo.

clazz.isInstance(obj)객체 obj가 클래스의 인스턴스 일 때마다 true clazz입니다.

그건:

clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)

너무 오래 항상 사실 clazzobj널이 있습니다.


3
이것은 Foo가 clazz와 같은 경우를 그리워합니다.이 경우에는 true를 반환합니다. 아래의 Pauls 최고 투표 답변은 다음과 같이 수정합니다
Rhubarb

3
clazz가 Foo 인 경우 clazz.isAssignableFrom (Foo.class)이 true라는 것에 동의합니다. 내가 다르게 말한 곳은?
uckelman

5
@Gili 이것은 uckelman이 말한 것이 아닙니다. 그의 답변을 다시 읽으십시오.
Puce

2
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> 인터페이스에서도 마찬가지입니다.
Puce

1
전문적 : 경우 obj입니다 null다음 clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)발생합니다 NullPointerException및 반환하지 true.
앤드류 Macheret

196

두 답변 모두 야구장에 있지만 완전한 답변은 아닙니다.

MyClass.class.isInstance(obj)인스턴스를 확인하기위한 것입니다. 매개 변수 obj가 널이 아니고를 MyClass올리지 않고 캐스트 할 수 있으면 true를 리턴합니다 ClassCastException. 즉, obj는 MyClass해당 서브 클래스 의 인스턴스입니다 .

MyClass.class.isAssignableFrom(Other.class)MyClass의 수퍼 클래스 또는 수퍼 인터페이스와 같거나 같으면 true를 반환합니다 Other. Other클래스 또는 인터페이스 일 수 있습니다. Other로 변환 할 수 있으면 true로 응답합니다 MyClass.

보여줄 작은 코드 :

public class NewMain
{
    public static void main(String[] args)
    {
        NewMain nm = new NewMain();
        nm.doit();
    }

    class A { }

    class B extends A { }

    public void doit()
    {
        A myA = new A();
        B myB = new B();
        A[] aArr = new A[0];
        B[] bArr = new B[0];

        System.out.println("b instanceof a: " + (myB instanceof A)); // true
        System.out.println("b isInstance a: " + A.class.isInstance(myB)); //true
        System.out.println("a isInstance b: " + B.class.isInstance(myA)); //false
        System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class)); //true
        System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class)); //false
        System.out.println("bArr isInstance A: " + A.class.isInstance(bArr)); //false
        System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr)); //true
        System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass())); //true
    }
}

10
예제에서 "b isAssignableFrom a :"인데 왜 코드가 A.class.isAssignableFrom(B.class)? 나는 출력으로 혼동되었다 :)
Roman Truba

4
ummm ... 모든 예제에서 "instanceOf"는 true를 반환합니다. "isAssignableFrom"은 true를 반환합니다.이 방법으로 차이를 볼 수 없습니다.
안드로이드 개발자

2
인쇄 된 텍스트가 코드와 일치하지 않아 혼동 될 수 있습니다. 예 : "System.out.println ("b isAssignableFrom a : "+ A.class.isAssignableFrom (B.class));"
polster

21
@Paul 독자가 "클래스의 서브 클래스의 인스턴스 인 객체와 클래스로 변환 가능한 객체의 유형 사이의 차이점은 무엇입니까?" 분명히, 당신은 당신이이 페이지에 도착했을 때와 같은 대답을 읽은 후에 독자들이 많은 질문을 남겼 음을 알 수 있습니다. 더 나은 대답은 실제로 그 차이 (또는 그 부족)를 설명 할 것입니다. 차이가 없으면 대답에는 "실제적인 차이가 없습니다"라고 직접 언급해야합니다.
Aleksandr Dubinsky

2
더 중요한 것은 독자가 자신의 목적에 무엇을 사용해야하는지 궁금해하는 것입니다. 질문의 의견에 따르면 객체가 null 인 경우 isAssignableFrom()a를 throw하고 false 만 반환합니다. 이것이 실제 답변입니다. NullPointerExceptionisInstance()
Andrew

6

그 두 가지 결과는 항상 같아야한다고 생각합니다. 차이점은 사용할 클래스의 인스턴스가 필요 isInstance하지만 Class사용할 객체 만 필요하다는 것 isAssignableFrom입니다.


이것은 100 % 사실이 아닙니다. Comparable.class.isAssignableFrom(Byte.class) == true하지만 Byte.class.isInstance(Comparable.class) == false. 다시 말해 isInstance()인터페이스에 대해서는 대칭이 아니며 서브 클래스에 대해서만 대칭입니다.
길리

6
@ 길리 : 당신은 거기에 약간 잘못있어. 객체가의 인스턴스가 아니기 Byte.class.isInstance(Comparable.class)때문에 false Class입니다 Byte. 에 대한 올바른 비교 Comparable.class.isAssignableFrom(Byte.class)IS Comparable.class.isInstance((byte) 1)사실이다.
ColinD

1
동의하지 않습니다. Javadoc을 찾으면 Byte확장 Number되고 클래스라는 것을 알 수 있습니다. (byte) 1와 동일하지 않습니다 Byte. 전자는 기본입니다. 후자는 클래스입니다.
길리

2
@Gili : 오토 박싱은 원시 캐스트 byteByte의 매개 변수 유형이 있기 때문 isInstance이다 Object.
ColinD

2
괜찮아. 내 원래 요점은 전화가 서로 정확히 대칭 적이지는 않지만 대답을 다시 읽으면이 주장을 한 적이 없으므로 맞습니다.
길리

6

간결하게하기 위해 아래 두 가지 API를 이해할 수 있습니다.

  1. X.class.isAssignableFrom(Y.class)

경우 XY같은 클래스, 또는 X이다 Y'의 슈퍼 클래스 나 슈퍼 인터페이스를 참, 그렇지 않으면 false를 반환합니다.

  1. X.class.isInstance(y)

말은 y클래스의 인스턴스 인 Y경우 XY같은 클래스, 또는 X이고 Y, 그렇지 않으면 false의 슈퍼 클래스 나 슈퍼 인터페이스는, true를 돌려줍니다.

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