Para os leitores: você está prestes a entrar em um buraco negro profundo, escuro, do qual nunca escapará. As diferenças são infinitas. Desistir agora, enquanto você ainda pode: stackoverflow.com/q/496928/1599699
esta falha o caso em que o Foo é o mesmo que clazz - no caso em que ele retorna verdadeira: Pauls resposta superior considerados abaixo corrige este
ruibarbo
3
Concordo que quando clazz é um Foo, então clazz.isAssignableFrom (Foo.class) é verdadeiro. Onde eu disse o contrário?
Uckelman
5
@ Gili Não foi isso que uckelman disse. Por favor, leia novamente a resposta dele.
Puce
2
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b)); -> também é verdade para interfaces.
Puce
1
Tecnicidade: Se objfor, nullentão clazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)lançará um NullPointerExceptione não retornará true.
Andrew Macheret
196
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.
Por que no seu exemplo "b isAssignableFrom a:" mas o código é A.class.isAssignableFrom(B.class)? I confuso com a saída :)
Roman Truba
4
ummm ... em todos os seus exemplos "instanceOf" retorna true se "isAssignableFrom" retorna true ... Eu não vejo a diferença dessa maneira.
desenvolvedor android
2
Tenha cuidado para que o texto impresso não corresponda ao código e possa ser confuso ... Exemplo: "System.out.println (" b isAssignableFrom a: "+ A.class.isAssignableFrom (B.class));"
Polster
21
@Paul A resposta, como está, não é útil, porque o leitor fica se perguntando "qual é a diferença entre um objeto ser uma instância de uma subclasse de uma classe e o tipo de objeto ser conversível na classe?" Certamente, você pode ver que deixou o leitor com tantas perguntas depois de ler sua resposta quanto ele ao chegar a esta página. Uma resposta melhor explicaria a diferença (ou a falta dela). Se não houver diferença, a resposta deve declarar diretamente: "não há diferença prática".
Aleksandr Dubinsky
2
Mais importante, o leitor fica se perguntando o que diabos usar para seus propósitos. De acordo com os comentários na pergunta, isAssignableFrom()lança a NullPointerExceptionse o objeto for nulo, enquanto isInstance()apenas retorna false. Essa é a verdadeira resposta.
18717 Andrew Andrew
6
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.
Isso não é 100% verdade. 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.
Gili
6
@ Gili: Você entendeu um pouco errado. 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.
ColinD 28/02
1
Discordo. Se você procurar o Javadoc Byte, descobrirá que ele se estende Numbere é uma classe. (byte) 1não é equivalente a Byte. O primeiro é um primitivo. Este último é uma classe.
Gili
2
@ Gil: Autoboxing lança primitivo bytepara Byteporque o tipo de parâmetro isInstanceé Object.
ColinD 28/02
2
OK. Meu argumento original era que as ligações não eram exatamente simétricas entre si, mas, depois de reler sua resposta, você nunca fez essa afirmação.
Gili
6
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.
NullPointerException
ifobj == null
.Respostas:
clazz.isAssignableFrom(Foo.class)
será verdadeiro sempre que a classe representada peloclazz
objeto for uma superclasse ou superinterface deFoo
.clazz.isInstance(obj)
será verdadeiro sempre que o objetoobj
for uma instância da classeclazz
.Isso é:
é sempre verdade desde que
clazz
eobj
seja nula.fonte
Byte b = 3; Comparable.class.isAssignableFrom(b.getClass()) == Comparable.class.isInstance(b));
-> também é verdade para interfaces.obj
for,null
entãoclazz.isAssignableFrom(obj.getClass()) == clazz.isInstance(obj)
lançará umNullPointerException
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 paraMyClass
sem gerar aClassCastException
. Em outras palavras, obj é uma instância deMyClass
ou suas subclasses.MyClass.class.isAssignableFrom(Other.class)
retornará true seMyClass
for o mesmo que, ou uma superclasse ou superinterface deOther
,.Other
pode ser uma classe ou uma interface. Responde true seOther
pode ser convertido em aMyClass
.Um pequeno código para demonstrar:
fonte
A.class.isAssignableFrom(B.class)
? I confuso com a saída :)isAssignableFrom()
lança aNullPointerException
se o objeto for nulo, enquantoisInstance()
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 oClass
objeto a ser usadoisAssignableFrom
.fonte
Comparable.class.isAssignableFrom(Byte.class) == true
masByte.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 umClass
objeto não é uma instância deByte
. A comparação correta paraComparable.class.isAssignableFrom(Byte.class)
éComparable.class.isInstance((byte) 1)
, o que é verdade.Byte
, descobrirá que ele se estendeNumber
e é uma classe.(byte) 1
não é equivalente aByte
. O primeiro é um primitivo. Este último é uma classe.byte
paraByte
porque o tipo de parâmetroisInstance
éObject
.Por uma questão de brevidade, podemos entender essas duas APIs, como abaixo:
X.class.isAssignableFrom(Y.class)
Se
X
eY
são da mesma classe, ouX
éY
superclasse ou super interface, retorne true, caso contrário, false.X.class.isInstance(y)
Say
y
é uma instância da classeY
, seX
eY
são da mesma classe, ouX
éY
superclasse ou super interface, retorna true, caso contrário, false.fonte