Java:en tiempo de compilación de la resolución y el "método más específico"
-
15-11-2019 - |
Pregunta
Las funciones sobrecargadas compute1()
, compute2()
, y compute5()
causar errores de compilación si se intentan utilizar a continuación:
package com.example.test.reflect;
class JLS15Test2
{
int compute1(Object o1, Integer i, Integer j) { return 1; }
int compute1(String s1, Integer i, int j) { return 2; }
int compute2(Object o1, Integer i, int j) { return 3; }
int compute2(String s1, Integer i, Integer j) { return 4; }
int compute3(Object o1, Integer i, int j) { return 5; }
int compute3(String s1, Integer i, int j) { return 6; }
int compute4(Object o1, Integer i, Integer j) { return 7; }
int compute4(String s1, Integer i, Integer j) { return 8; }
int compute5(Object o1, Integer i, Object j) { return 9; }
int compute5(String s1, Integer i, int j) { return 10; }
public static void main(String[] args)
{
JLS15Test2 y = new JLS15Test2();
// won't compile:
// The method compute1(Object, Integer, Integer) is ambiguous
// for the type JLS15Test2
// System.out.println(y.compute1("hi", 1, 1));
// Neither will this (same reason)
// System.out.println(y.compute2("hi", 1, 1));
System.out.println(y.compute3("hi", 1, 1));
System.out.println(y.compute4("hi", 1, 1));
// neither will this (same reason)
// System.out.println(y.compute5("hi", 1, 1));
}
}
Después de leer el JLS sección 15.12, creo entender...en la fase 2 (boxing/unboxing, no varargs) de la coincidencia de métodos sobrecargados, al determinar el "método más específico", el JLS dice (en efecto) que el método más específico es aquel cuyos parámetros formales son subtipos de otros métodos aplicables, y los tipos primitivos y Objetos (por ejemplo, int
y Integer
) nunca son subtipos de cada uno de los otros.Así Integer
es un subtipo de Integer
, y int
es un subtipo de int
, pero Integer
y int
son incompatibles w/r/t subtipo de comparaciones, por lo que ninguno de los compute1()
/compute2()
los pares tienen un método más específico.
(Mientras que en compute3()
y compute4()
el método con el String
el argumento es más específico que el método con el Object
argumento, por lo que el programa imprime 6 y 8.)
Es mi razonamiento correcto?
Solución
Sí, tu razonamiento es correcto.
Otros consejos
Si se agrega otro método que sólo se necesita una primitiva de tipo int y una caja Entero, no es capaz de resolver cuál es el método apropiado para el llamado:
int compute6(int i) { return 11;}
int compute6(Integer i){return 12;}
...
System.out.println(y.compute6(1));
Basado en eso, me imagino que tiene algo que ver con la interacción entre los diferentes parámetros, y no sólo el tipo separado de las relaciones.