Aprende programación






2 sept 2010

¿Que hará este código? - Parte 1


Este es un ejemplo que ví hace tiempo que me parece muy curioso.

Antes de nada, no vale probar la aplicación, debeis adivinarlo y razonar la respuesta. A ver si acertais que haría este algoritmo escrito en java y por qué.
class A{
}
class B extends A{
}
class Principal{
  public void ejecutar(A obj){
     System.out.println("Clase A");
  }
  public void ejecutar(B obj){
     System.out.println("Clase B");
  }
  public static void main(String arg[]){
     (new Principal()).ejecutar(null);
  }
}

Las opciones que teneis es:
a) Visualiza: Clase A
b) Visualiza: Clase B
c) No compila.
d) Error en tiempo de ejecución (Exception).

13 comentarios:

  1. Que bueno lo que pusiste Jorge. Me hizo pensar demasiado y no probé con el compilador pero yo digo que es el d. MUy probable que me equivoque pero según mi punto de vista cualquiera de las 4 opciones puede ser. XD

    ResponderEliminar
  2. La respuesta es (b), porque al momento de la selección Java siempre escoge la clase más específica. Es por esto que debe mostrar Clase B. Lo mismo aplica para sobreescritura.

    ResponderEliminar
  3. A ver, respuesta de uno que se está preparando la scjp...
    La C y la D descartadas.
    Entre la A y la B dudo, pero si tuviera que apostar mi cabeza diría la B porque B es la clase más baja en la jerarquía, o sea, la más específica.

    pero vamos que si fuera la A no me sorprendería.

    ResponderEliminar
  4. Una pregunta tonta, el tipo del parámetro es su tipo dinámico o su tipo estático? Me suena que es el estático, por lo tanto no debería compilar. Pero como no me acuerdo muy bien de esto mejor no voto, espero que me saquéis de dudas.

    ResponderEliminar
  5. Puestos a apostar, la C. No compila a no ser que le hagas un cast explicito.

    ResponderEliminar
  6. Venga, pues yo digo la A, porque el método está definido antes :D

    ResponderEliminar
  7. Para mi que la C.

    Java no busca los métodos de forma dinámica sino de forma estática, así que no compilaría ya que no sabria donde elnazar el método.

    ResponderEliminar
  8. Si estuviera correcto seria la opcion B. pero le falta algo asi que me decido por la opcion C

    ResponderEliminar
  9. Si no da un error de compilación (opción C), que arreglen el compilador ya ;-)

    Esta claro que la llamada ejecutar(null) es ambigua y se puede "saber" en tiempo de compilación.

    Una solución seria hacer un cast especifico
    ejecutar((A)null) o
    ejecutar((B)null)

    Como bien comentan arriba El Javato

    ResponderEliminar
  10. No veo porqué una llamada a null es ambigua.., sólo lo es para quién no conoce la ligadura dinámica por defecto de Java.

    La cuestión es saber dónde está especificada ésta... :)

    ResponderEliminar
  11. Muchas gracias a todos por contestar. Necesitaré un tiempo para argumentar una respuesta correcta. (De hecho no sé si la tendré). No esperaba que iban a haber tantas respuestas y tan lucidas y bién argumentadas como algunas.

    Imagino que ya lo habreis probado este caso y vereis que sale la (B). Sin embargo, si se ejecuta en lenguaje C++ dá error.

    La cuestión que quiero buscar, ¿está especificado este comportamiento por la Java Community Proccess?. ¿O tan solo es una casualidad que el programador del compiler JDK de SUN, como no sabía como implementarla, eligió uno a su vista o por casualidad?.

    A veces ocurren casos que no están en las especificaciones o comportamientos inesperados. El probar esta funcionalidad y ver que aparece el B en el JDK de SUN no significa que vaya a salir lo mismo en el OpenJDK si este caso no está especificado.

    Buscaré en dos documentos JSR, en el que trate de la sobrecarga y en el enlazado dinámico.

    Por lo que sé el enlazado dinámico trata de la ejecución de métodos en los objetos que apunta la referencia (siempre se va a la más específica si esta sobreescrita). Pero creo (digo solo creo) que no tiene relación con que una referencia apunte a null y sea el valor(null) el que vaya a la clase más específica. Sería al revés, una clase X va al método de la clase más específica del valor.

    En la especificación de la sobrecarga de métodos tampoco he encontrado nada. Pone unicamente que buscará el más apropiado pero sin concretar. Pero aún tengo que buscar más...

    Pues eso. Necesitaré algún tiempo para contestar.

    ResponderEliminar
    Respuestas
    1. Que pasó con la respuesta? ya te tomaste mas de 2 años yap =P

      Eliminar