¿Hay algo como instanceOf (Class <?> C) en Java?

87

Quiero comprobar si un objeto oes una instancia de la clase Co de una subclase de C.

Por ejemplo, si pes de la clase Pointquiero x.instanceOf(Point.class)ser truey también x.instanceOf(Object.class)ser true.

Quiero que funcione también para tipos primitivos en caja. Por ejemplo, si xes un Integerentonces x.instanceOf(Integer.class)debería ser true.

¿Existe tal cosa? Si no es así, ¿cómo puedo implementar tal método?

Snakile
fuente
manejar las clases en caja es un poco complicado
dfa

Respuestas:

172

Class.isInstance hace lo que quiere.

if (Point.class.isInstance(someObj)){
    ...
}

Por supuesto, no debería usarlo si pudiera usarlo instanceofen su lugar, pero para escenarios de reflexión a menudo es útil.

gustafc
fuente
6
@Ahamed es probablemente más lento, ¡pero lo que es peor es que es más difícil de entender! Si hay una forma muy sencilla de hacer algo, como por ejemplo if (a instanceof Point), pero lo haces de una manera más complicada, quien lea el código seguramente pensará "oh, tiene que haber una razón para que esto se haga de la manera difícil", y luego vaya a los documentos para averiguar en qué se Class.isInstancediferencia de instanceof. Pierdes el tiempo de tus compañeros.
gustafc
21

Quiero comprobar si un objeto o es una instancia de la clase c o de una subclase de c. Por ejemplo, si p es de clase Point, quiero x.instanceOf (Point.class)

¿Um que? ¿Qué son o, p y x?

Quiero que funcione también para tipos primitivos. Por ejemplo, si x es un número entero, entonces x.instanceOf (Integer.class) y también x.instanceOf (Object.class) deberían ser verdaderas.

No. Ni siquiera debería compilarse. Los primitivos no son objetos y no puede llamar a métodos sobre ellos.

De todos modos, hay tres cosas, una de las cuales definitivamente puede lograr lo que quieres (difieren un poco en dónde exactamente se aplican:

  • El instanceofoperador si conoce la clase en tiempo de compilación.
  • Class.isInstance () si desea comparar la clase de un objeto con una clase desconocida en el momento de la compilación.
  • Class.isAssignableFrom () si desea verificar la asignabilidad dados dos objetos de clase.
Michael Borgwardt
fuente
9
x instanceof Integer
x instanceof Object

solo tienes que usar la sintaxis correcta

para los tipos primitivos, tienes que hacerlo completamente diferente. Dado que no puede crear métodos para ellos, necesita una clase que mantenga el método. Entonces, en lugar de "x.instanceOf (Integer.Class)", debe llamar a "MyClassComparer.instanceOf (x, Integer.Class)" o algo así. Esto podría implementarse fácilmente mediante métodos de sobrecarga, pero no veo un caso en el que esa funcionalidad sea deseable en absoluto.

Erich Kitzmueller
fuente
4

De hecho, en Java hay un operador booleano llamado instanceof que se puede usar para determinar si un objeto es una instancia de una clase, una instancia de una subclase o una instancia de una clase que implementa una interfaz en particular.

if(obj instanceof SomeClass) {
    // Do something
}

El tutorial de Java tiene un buen ejemplo de este operador

Victor Hugo
fuente
1
no puede usar instanceof con tipos primitivos
dfa
4
Confundió tipos primitivos con objetos. Lea ... "Por ejemplo, si x es un número entero, entonces x.instanceOf (Integer.class) y también x.instanceOf (Object.class) deberían ser verdaderas". Vergüenza por votar negativamente todas las respuestas
victor hugo
Secundar (sp) la sugerencia de usar el Tutorial de Java. Es una buena referencia para aprender el idioma en sí.
luis.espinal
0

Tu puedes hacer:

if (foo instanceof classNameYouWantToCheck) 
fmsf
fuente
no puede usar instanceof con tipos primitivos
dfa
La clase fue solo para mostrar que debería escribir el nombre de la clase allí. Lo arreglaré
fmsf
0

"Quiero que funcione también para tipos primitivos. Por ejemplo, si x es un número entero, entonces x.instanceOf (Integer.class) y también x.instanceOf (Object.class) deberían ser verdaderas".

¿Por qué? Los tipos primitivos y los tipos de referencia están completamente separados. Un int primitivo no es un subtipo de Integer ni Object. El tipo de un valor primitivo siempre se conoce estáticamente en tiempo de compilación, por lo que no tiene sentido probar su tipo. Claro, puede enmarcar un valor primitivo y luego probar su tipo:

(Integer)5 instanceof Integer

Pero cuál sería el punto?

newacct
fuente
-2

Creo que estás confundido acerca de instanceof para objetos sin formato y genéricos

obj instanceof Class
obj instanceof Class<?> // this is the one you want
Paul Bors
fuente
2
No puede usar genéricos en el lado derecho del operador instanceof debido al borrado de tipo.
Matthias
2
No, eres tú quien está confundido al respecto. Tienes que usar el tipo crudo después instanceof.
Dawood ibn Kareem