Veo ganancia en el rendimiento al utilizar getClass()
y ==
operador de más de instanceOf
operador.
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));
¿Hay alguna pauta, cuál usar getClass()
o instanceOf
?
Dado un escenario: sé las clases exactas que se deben emparejar, es decir String
, Integer
(estas son clases finales), etc.
¿Es una instanceOf
mala práctica utilizar el operador?
java
class
instanceof
gota
fuente
fuente
Respuestas:
La razón por la que el desempeño de
instanceof
ygetClass() == ...
es diferente es que están haciendo cosas diferentes.instanceof
comprueba si la referencia de objeto en el lado izquierdo (LHS) es una instancia del tipo en el lado derecho (RHS) o algún subtipo .getClass() == ...
comprueba si los tipos son idénticos.Entonces, la recomendación es ignorar el problema de rendimiento y usar la alternativa que le brinde la respuesta que necesita.
No necesariamente. El uso excesivo de cualquiera
instanceOf
ogetClass()
puede ser "olor a diseño". Si no tiene cuidado, terminará con un diseño en el que la adición de nuevas subclases da como resultado una cantidad significativa de reelaboración de código. En la mayoría de situaciones, el enfoque preferido es utilizar polimorfismo.Sin embargo, hay casos en los que NO son "olor de diseño". Por ejemplo,
equals(Object)
debe probar el tipo real del argumento y devolverlofalse
si no coincide. Esto se hace mejor usandogetClass()
.Términos como "mejores prácticas", "malas prácticas", "olor de diseño", "antipatrón", etc. deben usarse con moderación y tratarse con sospecha. Fomentan el pensamiento en blanco o negro. Es mejor hacer sus juicios en contexto, en lugar de basarse puramente en dogmas; por ejemplo, algo que alguien dijo es "la mejor práctica".
fuente
code smell
para usar. Eso significa que es una consecuencia de un código de mal diseño (no polimórfico) que hace que lo uses. ¿Puedo inferir el uso de cualquiera de ellos de esta manera?instanceof
&getClass()
entra en escena debido a un mal diseño (no polimórfico) de código existente. ¿Estoy en lo correcto?instanceof
(por ejemplo) sea un mal diseño. Hay situaciones en las que puede ser la mejor solución. Lo mismo paragetClass()
. Repetiré que dije "uso excesivo" y no "uso" . Cada caso necesita ser juzgado por sus méritos ... no aplicando ciegamente alguna regla dogmática mal fundada.¿Desea hacer coincidir una clase exactamente , por ejemplo, solo coincidir en
FileInputStream
lugar de cualquier subclase deFileInputStream
? Si es así, usegetClass()
y==
. Normalmente haría esto en unequals
, para que una instancia de X no se considere igual a una instancia de una subclase de X; de lo contrario, puede tener problemas de simetría complicados. Por otro lado, suele ser más útil para comparar que dos objetos son de la misma clase que de una clase específica.De lo contrario, utilice
instanceof
. Tenga en cuenta que congetClass()
tendrá que asegurarse de tener una referencia no nula para comenzar, o obtendrá unNullPointerException
, mientrasinstanceof
que simplemente regresaráfalse
si el primer operando es nulo.Personalmente, diría que
instanceof
es más idiomático, pero usar cualquiera de ellos de manera extensiva es un olor a diseño en la mayoría de los casos.fuente
Sé que ha pasado un tiempo desde que se preguntó esto, pero ayer aprendí una alternativa.
Todos sabemos que puedes hacer:
pero ¿y si no sabes exactamente qué tipo de clase debe ser? genéricamente no puedes hacer:
ya que da un error de compilación.
En cambio, aquí hay una alternativa: isAssignableFrom ()
Por ejemplo:
fuente
isAssignableFrom
. La forma correcta de escribiro instanceof String
utilizando la reflexión esString.getClass().isInstance(o)
. El javadoc incluso lo dice: este método es el equivalente dinámico delinstanceof
operador del lenguaje Java .getClass () tiene la restricción de que los objetos solo son iguales a otros objetos de la misma clase, el mismo tipo de tiempo de ejecución, como se ilustra en la salida del siguiente código:
Salidas:
SubClass extiende ParentClass. subClassInstance es una instancia de ParentClass.
Diferentes getClass () devuelven resultados con subClassInstance y parentClassInstance.
fuente