Niech clazz
być niektóre Class
i obj
być niektóre Object
.java: Class.isInstance vs Class.isAssignableFrom
Czy
clazz.isAssignableFrom(obj.getClass())
zawsze taka sama jak
clazz.isInstance(obj)
?
Jeśli nie, jakie są różnice?
Niech clazz
być niektóre Class
i obj
być niektóre Object
.java: Class.isInstance vs Class.isAssignableFrom
Czy
clazz.isAssignableFrom(obj.getClass())
zawsze taka sama jak
clazz.isInstance(obj)
?
Jeśli nie, jakie są różnice?
clazz.isAssignableFrom(Foo.class)
będzie prawdziwe, gdy klasa reprezentowana przez obiekt clazz
jest nadklasą lub superinterfejsem Foo
.
clazz.isInstance(obj)
będzie prawdziwe, gdy obiekt obj
jest instancją klasy clazz
.
Czyli:
clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
jest zawsze prawdziwa.
to pomija przypadek, w którym Foo jest tym samym, co clazz - w takim przypadku zwraca true: Najczęściej komentowana odpowiedź Paula poniżej koryguje to – Rhubarb
Zgadzam się, że gdy clazz jest Foo, to clazz.isAssignableFrom (Foo.class) jest prawdziwe . Gdzie powiedziałem inaczej? – uckelman
To nie jest w 100% prawdziwe. 'Comparable.class.isAssignableFrom (Byte.class) == true' ale' Byte.class.isInstance (Comparable.class) == false'. Innymi słowy, 'isInstance()' nie jest symetryczne dla interfejsów, tylko dla podklas. – Gili
Myślę, że wynik dla tych dwojga powinien być zawsze taki sam. Różnica polega na tym, że potrzebujesz instancji klasy, aby użyć isInstance
, ale tylko obiektu Class
do używania isAssignableFrom
.
To nie jest w 100% prawdziwe. 'Comparable.class.isAssignableFrom (Byte.class) == true' ale' Byte.class.isInstance (Comparable.class) == false'. Innymi słowy, 'isInstance()' nie jest symetryczne dla interfejsów, tylko dla podklas. – Gili
@Gili: Tam jest trochę źle. 'Byte.class.isInstance (Comparable.class)' ma wartość false, ponieważ obiekt 'Class' nie jest instancją' Byte'. Prawidłowe porównanie z 'Comparable.class.isAssignableFrom (Byte.class)' to "Comparable.class.isInstance ((byte) 1)", co jest prawdą. – ColinD
Nie zgadzam się. Jeśli spojrzysz na Javadoc 'Byte', odkryjesz, że rozszerza on' Number' i jest klasą. '(byte) 1' nie jest równoważne' Byte'. Ten pierwszy jest prymitywny. Ta ostatnia jest klasą. – Gili
Obie odpowiedzi są dostępne w sklepie, ale żadna z nich nie jest kompletna.
MyClass.class.isInstance(obj)
służy do sprawdzania instancji. Zwraca wartość true, gdy parametr obj jest wartością inną niż null i można go przenieść do MyClass
bez podnoszenia wartości ClassCastException
. Innymi słowy, obj jest instancją MyClass
lub jej podklasami.
MyClass.class.isAssignableFrom(Other.class)
zwróci true, jeśli MyClass
jest takie samo lub superklasy lub superinterfejsu, Other
. Other
może być klasą lub interfejsem. Odpowiada to prawdzie, jeśli można przekonwertować Other
na MyClass
.
Trochę kodu wykazać:
public class NewMain
{
public static void main(String[] args)
{
NewMain nm = new NewMain();
nm.doit();
}
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));
System.out.println("b isInstance a: " + A.class.isInstance(myB));
System.out.println("a isInstance b: " + B.class.isInstance(myA));
System.out.println("b isAssignableFrom a: " + A.class.isAssignableFrom(B.class));
System.out.println("a isAssignableFrom b: " + B.class.isAssignableFrom(A.class));
System.out.println("bArr isInstance A: " + A.class.isInstance(bArr));
System.out.println("bArr isInstance aArr: " + aArr.getClass().isInstance(bArr));
System.out.println("bArr isAssignableFrom aArr: " + aArr.getClass().isAssignableFrom(bArr.getClass()));
}
class A
{
}
class B extends A
{
}
}
a wyjście:
b instanceof a: true
b isInstance a: true
a isInstance b: false
b isAssignableFrom a: true
a isAssignableFrom b: false
bArr isInstance A: false
bArr isInstance aArr: true
bArr isAssignableFrom aArr: true
Linie od trzeciej do ostatniej i drugiej do ostatniej mówią "bArr isInstance aArr", ale kod jest inny. –
Dlaczego w twoim przykładzie "b isAssignableFrom a:", ale kod jest "A.class.isAssignableFrom (B.class)"? Pomyliłem się przez wyjście :) –
MyClass.class.isInstance (obj) będzie również działał dla interfejsów: _Jeśli ten obiekt Class reprezentuje interfejs, ta metoda zwraca wartość true, jeśli klasa lub dowolna nadklasa podanego argumentu Object implementuje ten interfejs. – Patrick
Dla zwięzłości, możemy zrozumieć te dwa API jak poniżej:
Jeśli X i Y są tą samą klasą lub X jest super-klasą super interfejsu Y, zwracana jest wartość true, w przeciwnym razie false.
Powiedzmy y jest instancją klasy Y, jeśli X i Y są tą samą klasą lub X jest super-klasą super interfejsu Y, zwracają true, w przeciwnym razie false.
jeśli obj == null, druga zwraca wartość false, pierwsza nie. ;) –
@PeterLawrey, pierwszy rzuci 'NullPointerException', jeśli' obj == null'. – ryvantage
Znaleziono kilka odpowiedzi na próbki z hrere: http://www.mytechnotes.biz/2012/07/java-instanceof-isassignablefrom-or.html –