2012-07-02 9 views
20

Supongamos, tenemos:¿Cómo funciona `isInstanceOf`?

class B 
class A extends B 
trait T 

entonces se cumple:

val a: A with T = new A with T 
a.isInstanceOf[B] // result is true ! 

¿Es correcto decir, los isInstanceOf método comprueba, si hay al menos un tipo (no todos los tipos) que coincide el lado derecho en una relación de subtipo?

A primera vista, pensé con un valor de tipo A with T no puede ser un subtipo de B, porque AyT no son ambos subtipos de B. Pero es AoT es un subtipo de B - ¿es eso correcto?

+4

Sí, eso es todo. – Nicolas

+0

Aquí una visión general rápida de la igualdad de objetos http://joelabrahamsson.com/learning-scala-part-eight-scalas-type-hierarchy-and-object-equality/ – Jaider

Respuesta

30

isInstanceOf mira si hay una entrada correspondiente en la cadena de herencia. La cadena de A with T incluye A, B y T, por lo que a.isInstanceOf[B] debe ser verdadero.

edición:

En realidad, el código de bytes generada llamadas javas instanceof, por lo que sería a instanceof B en Java. Una llamada un poco más compleja como a.isInstanceOf[A with T] sería (a instanceof A) && (a instanceof T).

+1

Gracias por la información de fondo, que ayudó mucho.¿Sabes dónde puedo encontrar más información de fondo sobre el método 'isInstanceOf' de Scala? La API de Scala no dice mucho al respecto. –

+0

No hay mucho que contar. Es solo 'instanceof'. – drexin

10

A primera vista, pensé con un valor de tipo A con T no puede ser un subtipo B del

Hay son dos conceptos erróneos aquí. Primero, que el tipo estático de una instancia influye en el resultado de isInstanceOf: no hay ninguno. Para que quede claro, al hacer a.isInstanceOf[B], el hecho de que a sea del tipo A with Tno es relevante.

El método isInstanceOf se implementa en el nivel de bytecode por la JVM. Mira la información de clase cada instancia lleva, y comprueba si B una de las clases (la clase de la instancia misma y sus antecesores), o una de las interfaces implementadas. Esa es la relación "es-a": "a es una B".

Técnicamente, isInstanceOf es parte de la reflexión de Java, donde se conoce como instanceof.

El segundo error es que la herencia puede de alguna manera eliminar un tipo principal. Eso nunca sucede: la herencia solo agrega tipos, nunca los elimina. El tipo A with T es un A, un B, un T, un AnyVal y un Any. Entonces, incluso si isInstanceOf mirara el tipo A with T, aún así devolvería verdadero.

+0

¿Sabes cómo puedo probar 'Null' y' Nothing' son subtipos de todas las cosas en el REPL? '" A ".isInstanceOf [Null]' errors? como hace 'Nada'? Supongo que eso tiene sentido; es decir, '" A "instanceof null' no funcionaría en Java. ¿Tengo que tomar la palabra de los documentos? – Toby

+0

@Toby 'Nothing' no existe en Java, ya que trata las clases y primitivas y cosas distintas, y' instanceof' solo se refiere a la primera. Además, 'Null' tampoco existe en Java, que no tiene ningún concepto de" fondo ". –