Vejo ganho no desempenho ao usar operador getClass()
e operador.==
instanceOf
Object str = new Integer("2000");
long starttime = System.nanoTime();
if(str instanceof String) {
System.out.println("its string");
} else {
if (str instanceof Integer) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
starttime = System.nanoTime();
if(str.getClass() == String.class) {
System.out.println("its string in equals");
} else {
if(str.getClass() == Integer.class) {
System.out.println("its integer");
}
}
System.out.println((System.nanoTime()-starttime));
Existe alguma diretriz, qual usar getClass()
ou instanceOf
?
Dado um cenário: eu conheço as classes exatas a serem correspondidas, ou seja String
, Integer
(essas são as classes finais), etc.
Está usando uma instanceOf
má prática do operador?
java
class
instanceof
bolha
fonte
fonte
Respostas:
A razão pela qual o desempenho de
instanceof
egetClass() == ...
é diferente é que eles estão fazendo coisas diferentes.instanceof
testa se a referência do objeto no lado esquerdo (LHS) é uma instância do tipo no lado direito (RHS) ou algum subtipo .getClass() == ...
testa se os tipos são idênticos.Portanto, a recomendação é ignorar o problema de desempenho e usar a alternativa que fornece a resposta de que você precisa.
Não necessariamente. O uso excessivo de um
instanceOf
ou outrogetClass()
pode ser "cheiro de design". Se você não for cuidadoso, acabará com um design em que a adição de novas subclasses resulta em uma quantidade significativa de retrabalho de código. Na maioria das situações, a abordagem preferida é usar polimorfismo.No entanto, há casos em que NÃO são "cheiro de design". Por exemplo,
equals(Object)
você precisa testar o tipo real do argumento e retornarfalse
se ele não corresponder. É melhor fazer isso usandogetClass()
.Termos como "melhor prática", "má prática", "cheiro de design", "antipadrão" e assim por diante devem ser usados com moderação e tratados com suspeita. Eles encorajam o pensamento preto-ou-branco. É melhor fazer seus julgamentos no contexto, em vez de baseados puramente em dogmas; por exemplo, algo que alguém disse é "melhor prática".
fonte
code smell
para usar qualquer um. Isso significa que é uma consequência de um código de design ruim (não polimórfico) que leva você a usar qualquer um deles. posso inferir o uso de qualquer um deles desta forma?instanceof
&getClass()
entra em cena devido ao mau design existente (não polimórfico) do código. estou correcto?instanceof
(por exemplo) é um design ruim. Existem situações em que pode ser a melhor solução. O mesmo paragetClass()
. Vou repetir que disse "overuse" e não "use" . Cada caso precisa ser julgado por seus méritos ... não pela aplicação cega de alguma regra dogmática infundada.Você deseja corresponder exatamente a uma classe , por exemplo, apenas correspondendo em
FileInputStream
vez de qualquer subclasse deFileInputStream
? Se sim, usegetClass()
e==
. Eu normalmente faria isso em umequals
, de forma que uma instância de X não fosse considerada igual a uma instância de uma subclasse de X - caso contrário, você pode ter problemas de simetria complicados. Por outro lado, isso geralmente é mais útil para comparar que dois objetos são da mesma classe do que de uma classe específica.Caso contrário, use
instanceof
. Observe que comgetClass()
você precisará garantir que tem uma referência não nula para começar, ou você obterá umNullPointerException
, enquantoinstanceof
apenas retornaráfalse
se o primeiro operando for nulo.Pessoalmente, eu diria que
instanceof
é mais idiomático - mas usar qualquer um deles extensivamente é um cheiro de design na maioria dos casos.fonte
Eu sei que já faz um tempo desde que isso foi perguntado, mas eu aprendi uma alternativa ontem
Todos nós sabemos que você pode fazer:
mas e se você não souber exatamente que tipo de aula precisa ser? você não pode fazer genericamente:
pois dá um erro de compilação.
Em vez disso, aqui está uma alternativa - isAssignableFrom ()
Por exemplo:
fonte
isAssignableFrom
. A maneira correta de escrevero instanceof String
usando reflexão éString.getClass().isInstance(o)
. O javadoc até diz isso: este método é o equivalente dinâmico doinstanceof
operador da linguagem Java .getClass () tem a restrição de que os objetos são iguais apenas a outros objetos da mesma classe, o mesmo tipo de tempo de execução, conforme ilustrado na saída do código abaixo:
Saídas:
SubClass estende ParentClass. subClassInstance é instanceof ParentClass.
GetClass () diferente retorna resultados com subClassInstance e parentClassInstance.
fonte