Vamos clazz
ser alguns Class
e obj
ser alguns Object
.
É
clazz.isAssignableFrom(obj.getClass())
sempre o mesmo que
clazz.isInstance(obj)
?
Se não, quais são as diferenças?
NullPointerException
if obj == null
.
Vamos clazz
ser alguns Class
e obj
ser alguns Object
.
É
clazz.isAssignableFrom(obj.getClass())
sempre o mesmo que
clazz.isInstance(obj)
?
Se não, quais são as diferenças?
NullPointerException
if obj == null
.
Respostas:
clazz.isAssignableFrom(Foo.class)
será verdadeiro sempre que a classe representada pelo clazz
objeto for uma superclasse ou superinterface de Foo
.
clazz.isInstance(obj)
será verdadeiro sempre que o objeto obj
for uma instância da classe clazz
.
Isso é:
clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
é sempre verdade desde que clazz
e obj
seja nula.
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b));
-> também é verdade para interfaces.
obj
for, null
então clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
lançará um NullPointerException
e não retornará true
.
Ambas as respostas estão no estádio, mas também não é uma resposta completa.
MyClass.class.isInstance(obj)
é para verificar uma instância. Retorna true quando o parâmetro obj é não nulo e pode ser convertido para MyClass
sem gerar a ClassCastException
. Em outras palavras, obj é uma instância de MyClass
ou suas subclasses.
MyClass.class.isAssignableFrom(Other.class)
retornará true se MyClass
for o mesmo que, ou uma superclasse ou superinterface de Other
,. Other
pode ser uma classe ou uma interface. Responde true se Other
pode ser convertido em a MyClass
.
Um pequeno código para demonstrar:
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
}
}
A.class.isAssignableFrom(B.class)
? I confuso com a saída :)
isAssignableFrom()
lança a NullPointerException
se o objeto for nulo, enquanto isInstance()
apenas retorna false. Essa é a verdadeira resposta.
Eu acho que o resultado para esses dois sempre deve ser o mesmo. A diferença é que você precisa de uma instância da classe para usar, isInstance
mas apenas o Class
objeto a ser usado isAssignableFrom
.
Comparable.class.isAssignableFrom(Byte.class) == true
mas Byte.class.isInstance(Comparable.class) == false
. Em outras palavras, isInstance()
não é simétrico para interfaces, apenas para subclasses.
Byte.class.isInstance(Comparable.class)
é falso porque um Class
objeto não é uma instância de Byte
. A comparação correta para Comparable.class.isAssignableFrom(Byte.class)
é Comparable.class.isInstance((byte) 1)
, o que é verdade.
Byte
, descobrirá que ele se estende Number
e é uma classe. (byte) 1
não é equivalente a Byte
. O primeiro é um primitivo. Este último é uma classe.
byte
para Byte
porque o tipo de parâmetro isInstance
é Object
.
Por uma questão de brevidade, podemos entender essas duas APIs, como abaixo:
X.class.isAssignableFrom(Y.class)
Se X
e Y
são da mesma classe, ou X
é Y
superclasse ou super interface, retorne true, caso contrário, false.
X.class.isInstance(y)
Say y
é uma instância da classe Y
, se X
e Y
são da mesma classe, ou X
é Y
superclasse ou super interface, retorna true, caso contrário, false.