¿Por qué una lista <SuperClass> Objeto se puede lanzar a un objeto de subclase?

Ofiuco Hahn:

He encontrado que, el caso 1 y el caso 3 se puede compilar sin errores, pero el caso 2. (SubClassB extiende SuperClassA, que es la clase abstracta) Lo que me pregunto es, ¿por qué casos 1 y 3 no tienen errores de compilación. Si se trata de un error de JDK, ¿por qué el caso 2 no puede pasar la comprobación de reparto?

// case 1        
List<SuperClassA> a = new ArrayList<>();
SubClassB b = (SubClassB) a; 

// case 2
List<Number> m = new ArrayList<>();
Long n = (Long) m; //Error:(xx,yy) java: incompatible types: java.util.List<java.lang.Number> cannot be converted to java.lang.Long

// case 3
List<Exception> e = new ArrayList<>();
RuntimeException d = (RuntimeException) e;
barredora:

Tenga en cuenta que el caso 1 y el caso 3 se fallará tanto en tiempo de ejecución.

En tiempo de compilación, el compilador se quejará moldes sobre incompatibles sólo si la especificación de lenguaje lo dice. La especificación de lenguaje permite a los casos 1 y 3 porque no van a 100% fallar.

Caso 1 no será 100% fallar, por lo que se refiere al compilador, ya que piensa que apuede contener una instancia de cualquier tipo que implementa List<SuperClassA>. ¿Qué pasa si hay una subclase de SubclassBque efectivamente en marcha List<SuperClassA>? ¿Y si aen realidad contiene una instancia de esa subclase de SubclassB? A continuación, el molde tendría éxito!

Lo mismo vale para el caso 2. ¿Qué pasa si hay una subclase de RuntimeExceptionque efectivamente en marcha List<Exception>? ¿Y si een realidad contiene una instancia de esa subclase de RuntimeException? A continuación, el molde tendría éxito!

Caso 2 muestra un error porque Longse ofrecen final. Allí no podía ser una subclase que implementa List<Number>, por lo que definitivamente va a fallar.

Esto se especifica en §5.5.1 de la especificación (cursiva son los bits correspondientes):

Dado un tiempo de compilación tipo de referencia S (fuente) y un tipo de referencia de tiempo de compilación T (objetivo), existe una conversión de colada de S a T si no se producen errores de tiempo de compilación debido a las siguientes reglas.

...

Si S es un tipo de interfaz:

  • Si T es un tipo de matriz, entonces S debe ser el tipo java.io.Serializableo Cloneable(las únicas interfaces implementadas por arrays), o un tiempo de compilación se produce error.

  • Si T es un tipo de clase o interfaz que no es final(§8.1.1), entonces si existe un supertipo X de T, y un supertipo Y de S, de manera que tanto X como Y son tipos parametrizados provably distintas, y que el borraduras de X e y son los mismos, se produce un error de tiempo de compilación.

De lo contrario, el reparto es siempre legal en tiempo de compilación (porque incluso si T no implementa S, una subclase de T fuerzas).

  • Si T es un tipo de clase que es final , a continuación:

    - Si S no es un tipo parametrizado o un tipo de prima, entonces T debe implementar S, o se produce un error en tiempo de compilación.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=183718&siteId=1
Recomendado
Clasificación