2009-10-09 7 views
50

Si escribo esta línea en Java:¿Qué sobrecarga se seleccionará para nulo en Java?

JOptionPane.showInputDialog(null, "Write something"); 

Qué método será llamado?

  • showInputDialog(Component parent, Object message)
  • showInputDialog(Object message, Object initialSelectionValue)

puedo probarlo. Pero en otros casos similares a esto, quiero saber qué sucede.

+3

que en realidad es una buena pregunta, incluso si se las ingenió (que no se desea llamar a la primera, ya que es idéntica a 'JOptionPane.showInputDialog ("Escribir algo"); ' – Powerlord

Respuesta

61

El más específica método será llamado - en este caso

showInputDialog(Component parent, Object message) 

Esto viene generalmente bajo la "Determine Method Signature" paso de la resolución de sobrecarga en la especificación (15.12.2) y, en particular "Choosing the Most Specific Method".

Sin entrar en los detalles (que se puede leer igual de bien en la especificación como en este caso), la introducción da un buen resumen:

Si más de un método de la barra es a la vez accesible y aplicable a una invocación al método , es necesario elegir uno para proporcionar el descriptor para el envío del método de tiempo de ejecución . El lenguaje de programación Java usa la regla que el método más específico es elegido.

La intuición informal es que uno método es más específico que otro si cualquier invocación manejado por el primero método podría ser transmitida a la otra uno sin un error de tipo de tiempo de compilación.

+4

¿Qué pasa cuando se llama a' f (null) 'cuando se definen los métodos' f (Integer i) 'y' f (String s) '? Ninguno parece más específico que el otro. – Stephan202

+0

@ Stephan202: En Eclipse, I get 'El método f (Integer) es ambiguo para el tipo ExampleClass' Esto fue con métodos estáticos – Powerlord

+0

@ R. Bemrose: a juzgar por la respuesta de Bill, esto también se aplicará a los métodos no estáticos. Gracias por probar! – Stephan202

9

Ninguno. Obtendrá un error de compilación que le pedirá que aclare a qué método desea llamar. Puede hacerlo mediante la fundición de forma explícita el primer argumento:

showInputDialog((Object) null, "Write something"); 

o

showInputDialog((Component) null, "Write something"); 

actualización Debería haber sabido - Nunca dudar de Jon Skeet. El problema al que me he referido anteriormente solo ocurre cuando es imposible determinar qué método es más específico. Aquí hay un caso de prueba:

public class Test { 

    public void doSomething(String arg1, Object arg2) { 
    System.out.println("String, Object"); 
    } 

    public void doSomething(Object arg1, String arg2) { 
    System.out.println("Object, String"); 
    } 

    public static void main(String[] args) { 
    Test test = new Test(); 
    test.doSomething(null, null); 
    } 
} 

Lo anterior dará un error de compilación.

+2

Probado y allí no hay error de compilación. – JCasso

+0

@jcasso - Veo un error de compilación en la línea "doSomething", que dice "The met hod doSomething (String, Object) es ambiguo para el tipo " – CPerkins

+2

@CPerkins - sí, el comentario de jcasso se refiere a mi respuesta original (incorrecta) donde dije que' showInputDialog() 'arrojaría un error de compilación mientras que no lo haría. – ChssPly76

12

En su caso particular, se llamará al método más específico. En general, sin embargo, hay algunos casos donde la firma del método puede ser ambigua.Considere lo siguiente:

public class Main { 

    public static void main(String[] args) { 
     Main m = new Main(); 
     m.testNullArgument(null); 
    } 

    private void testNullArgument(Object o) 
    { 
     System.out.println("An Object was passed..."); 
    } 

    private void testNullArgument(Integer i) 
    { 
     System.out.println("An Integer was passed..."); 
    } 

    private void testNullArgument(String s) 
    { 
     System.out.println("A String was passed..."); 
    } 
} 

En este caso, el compilador no puede decidir entre el método que toma un entero y el método que toma una cadena. Cuando intento compilar que, consigo

reference to testNullArgument is ambiguous, both method testNullArgument(java.lang.Integer) in testnullargument.Main and method testNullArgument(java.lang.String) in testnullargument.Main match 
+4

Eso tiene sentido. Integer y String son "iguales" en términos de especificidad, mientras que Object es el padre de ambos, por lo que es más vago. Ahora, si eliminaste el método String, se llamaría el entero. –

+2

@Thomas: Eso es correcto. Parece que no importa qué tan lejos estén las diferentes ramas del árbol de herencia las dos clases ambiguas, ya que String extiende directamente el objeto, mientras que el entero extiende el número. –

Cuestiones relacionadas