titledborder poner ejemplo borde java interface casting

poner - setbounds java



Java fundido en las interfaces (4)

Cuando echas o1 y o3 con (I2) , le dices al compilador que la clase del objeto es en realidad una subclase de su tipo declarado, y que esta subclase implementa I2 .

La clase Integer es final , por lo que o3 no puede ser una instancia de una subclase de Integer : el compilador sabe que estás mintiendo. Sin embargo, C1 no es final, por lo que o1 podría ser una instancia de un subtipo de C1 que implemente I2 .

Si haces C1 final, el compilador también se quejará:

interface I1 { } interface I2 { } final class C1 implements I1 { } class C2 implements I2 { } public class Test{ public static void main(){ C1 o1 = new C1(); C2 o2 = new C2(); Integer o3 = new Integer(4); I2 y = (I2)o3; //compiler complains here !! I2 x = (I2)o1; //compiler complains too } }

¿Puede alguien explicarme cómo el compilador no se queja en el primer casting, pero se queja en el segundo?

interface I1 { } interface I2 { } class C1 implements I1 { } class C2 implements I2 { } public class Test{ public static void main(){ C1 o1 = new C1(); C2 o2 = new C2(); Integer o3 = new Integer(4); I2 x = (I2)o1; //compiler does not complain I2 y = (I2)o3; //compiler complains here !! } }


De acuerdo con el capítulo 5 de JLS

5.5.1. Tipo de referencia de lanzamiento

Dado un tipo de referencia de tiempo de compilación S (origen) y un tipo de referencia de tiempo de compilación T (destino), existe una conversión de conversión de S a T si no se producen errores en tiempo de compilación debido a las siguientes reglas. Si T es un tipo de interfaz:

Si S no es una clase final (§8.1.1), entonces, si existe un supertipo X de T, y un supertipo Y de S, de modo que tanto X como Y son tipos parametrizados claramente distintos, y que las borraduras de X y Y son iguales, se produce un error en tiempo de compilación.

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

Si S es una clase final (§8.1.1), entonces S debe implementar T, o se produce un error en tiempo de compilación.


Eso es porque la clase Integer es definitiva y C1 no lo es. Por lo tanto, un objeto Integer no puede implementar I2, mientras que un objeto C1 podría hacerlo si es una instancia de una subclase de C1 que implementa I2.


Según JLS 5.5.1 - Fundición de tipo de referencia , la (s) regla (s) se aplican:

  • Si T es un tipo de clase, entonces | S | <: | T |, o | T | <: | S |. De lo contrario, se produce un error en tiempo de compilación.

    I2 y = (I2)o3; //compiler complains here !!

En este caso, un Integer e I2 no están relacionados de ninguna manera, por lo que se produce un error en tiempo de compilación. Además, dado que Integer es final , no hay relación entre Integer e I2 .

I2 e I1 pueden relacionarse debido a que ambos son una interfaz de marcador (no hay contrato).

En cuanto al código compilado, la regla sigue:

  • Si S no es una clase final (§8.1.1), entonces, si existe un supertipo X de T, y un supertipo Y de S, de modo que tanto X como Y son tipos parametrizados claramente distintos, y que las borraduras de X y Y son iguales, se produce un error en tiempo de compilación.

S es o1 y T es I2 .

Espero que esto ayude.