Vamos clazzser alguns Classe objser alguns Object.
É
clazz.isAssignableFrom(obj.getClass())
sempre o mesmo que
clazz.isInstance(obj)
?
Se não, quais são as diferenças?
NullPointerExceptionif obj == null.
Vamos clazzser alguns Classe objser alguns Object.
É
clazz.isAssignableFrom(obj.getClass())
sempre o mesmo que
clazz.isInstance(obj)
?
Se não, quais são as diferenças?
NullPointerExceptionif obj == null.
Respostas:
clazz.isAssignableFrom(Foo.class)será verdadeiro sempre que a classe representada pelo clazzobjeto for uma superclasse ou superinterface de Foo.
clazz.isInstance(obj)será verdadeiro sempre que o objeto objfor uma instância da classe clazz.
Isso é:
clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
é sempre verdade desde que clazze objseja nula.
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> também é verdade para interfaces.
objfor, nullentão clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)lançará um NullPointerExceptione 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 MyClasssem gerar a ClassCastException. Em outras palavras, obj é uma instância de MyClassou suas subclasses.
MyClass.class.isAssignableFrom(Other.class)retornará true se MyClassfor o mesmo que, ou uma superclasse ou superinterface de Other,. Otherpode ser uma classe ou uma interface. Responde true se Otherpode 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 NullPointerExceptionse 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, isInstancemas apenas o Classobjeto a ser usado isAssignableFrom.
Comparable.class.isAssignableFrom(Byte.class) == truemas 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 Classobjeto 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 Numbere é uma classe. (byte) 1não é equivalente a Byte. O primeiro é um primitivo. Este último é uma classe.
bytepara Byteporque 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 Xe Ysão da mesma classe, ou Xé Ysuperclasse ou super interface, retorne true, caso contrário, false.
X.class.isInstance(y)Say yé uma instância da classe Y, se Xe Ysão da mesma classe, ou Xé Ysuperclasse ou super interface, retorna true, caso contrário, false.