Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

325
Vistas
¿Por qué javac permite algunos lanzamientos imposibles y otros no?

Si trato de enviar un String a java.util.Date , el compilador de Java detecta el error. Entonces, ¿por qué el compilador no marca lo siguiente como un error?

 List<String> strList = new ArrayList<>(); Date d = (Date) strList;

Por supuesto, la JVM lanza una ClassCastException en tiempo de ejecución, pero el compilador no la marca.

El comportamiento es el mismo con javac 1.8.0_212 y 11.0.2.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

El elenco es técnicamente posible. Javac no puede probar fácilmente que no es así en su caso y el JLS en realidad define esto como un programa Java válido, por lo que marcar un error sería incorrecto.

Esto se debe a que List es una interfaz. Por lo tanto, podría tener una subclase de una Date que realmente implemente List disfrazada de List aquí, y luego convertirla en Date estaría perfectamente bien. Por ejemplo:

 public class SneakyListDate extends Date implements List<Foo> { ... }

Y luego:

 List<Foo> list = new SneakyListDate(); Date date = (Date) list; // This one is valid, compiles and runs just fine

Es posible que no siempre sea posible detectar un escenario de este tipo, ya que requeriría información de tiempo de ejecución si la instancia proviene, por ejemplo, de un método. E incluso si, requeriría mucho más esfuerzo para el compilador. El compilador solo evita conversiones que son absolutamente imposibles debido a que no hay forma de que el árbol de clases coincida en absoluto. Que no es el caso aquí, como se ve.

Tenga en cuenta que el JLS requiere que su código sea un programa Java válido. En 5.1.6.1. Conversión de referencia de reducción permitida dice:

Existe una conversión de referencia de restricción del tipo de referencia S al tipo de referencia T si todo lo siguiente es verdadero :

  • [...]
  • Se aplica uno de los siguientes casos:
    • [...]
    • S es un tipo de interfaz, T es un tipo de clase y T no nombra una clase final .

Entonces, incluso si el compilador pudiera darse cuenta de que su caso es realmente imposible, no se le permite marcar un error porque JLS lo define como un programa Java válido.

Solo se permitiría mostrar una advertencia.

over 4 years ago · Santiago Trujillo Denunciar

0

Consideremos una generalización de su ejemplo:

 List<String> strList = someMethod(); Date d = (Date) strList;

Estas son las principales razones por las que Date d = (Date) strList; no es un error de compilación.

  • La razón intuitiva es que el compilador (en general) no conoce el tipo preciso del objeto devuelto por esa llamada al método. Es posible que además de ser una clase que implementa List , también sea una subclase de Date .

  • La razón técnica es que la especificación del lenguaje Java "permite" la conversión de referencia de restricción que corresponde a este tipo de conversión. Según JLS 5.1.6.1 :

    "Existe una conversión de referencia de restricción del tipo de referencia S al tipo de referencia T si todo lo siguiente es verdadero:"

    ...

    5) " S es un tipo de interfaz, T es un tipo de clase y T no nombra una clase final ".

    ...

    En un lugar diferente, JLS también dice que se puede lanzar una excepción en tiempo de ejecución...

    Tenga en cuenta que la determinación de JLS 5.1.6.1 se basa únicamente en los tipos declarados de las variables involucradas en lugar de los tipos de tiempo de ejecución reales. En el caso general, el compilador no conoce ni puede conocer los tipos reales de tiempo de ejecución.


Entonces, ¿por qué el compilador de Java no puede determinar que la conversión no funcionará?

  • En mi ejemplo, la llamada a someMethod podría devolver objetos con una variedad de tipos. Incluso si el compilador pudiera analizar el cuerpo del método y determinar el conjunto preciso de tipos que podrían devolverse, no hay nada que impida que alguien lo cambie para devolver diferentes tipos... después de compilar el código que lo llama. Esta es la razón básica por la que JLS 5.1.6.1 dice lo que dice.

  • En su ejemplo, un compilador inteligente podría darse cuenta de que el elenco nunca puede tener éxito. Y está permitido emitir una advertencia en tiempo de compilación para señalar el problema.

Entonces, ¿por qué no se le permite a un compilador inteligente decir que esto es un error de todos modos?

  • Porque el JLS dice que este es un programa válido. Período. Cualquier compilador que llamara a esto un error no sería compatible con Java.

  • Además, cualquier compilador que rechace programas Java que JLS y otros compiladores digan que son válidos, es un impedimento para la portabilidad del código fuente de Java.

over 4 years ago · Santiago Trujillo Denunciar

0

5.5.1. Tipo de referencia Fundición:

Dado un tipo de referencia en tiempo de compilación S (fuente) y un tipo de referencia en 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 S es un tipo de interfaz:

  • [...]

  • Si T es una clase o un tipo de interfaz que no es final, entonces si existe un supertipo X de T y un supertipo Y de S , de modo que tanto X como Y sean tipos parametrizados distintos y que los borrados de X e Y son iguales, se produce un error en tiempo de compilación.

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

List<String> es S y Date es T en su caso.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda