Estoy haciendo mis ejercicios de clase Java. Tengo este código que contiene un método sobrecargado:
class A {
// Overloaded method
public void f(int n, float x) {
System.out.println("f(int n, float x) n = " + n + " x = " + x);
}
private void f(long q, double y) {
System.out.println("f(long q, double y) q = " + q + " y = " + y);
}
public void f(double y1, double y2) {
System.out.println("f(double y1, double y2) y1 = " + y1 + " y2 = " + y2);
}
public void g() {
int n = 1;
long q = 12;
float x = 1.5f;
double y = 2.5;
System.out.println("--- dans g ");
f(n, q);
f(q, n);
f(n, x);
f(n, y);
}
}
Principal:
public static void main(String[] args){
A a = new A() ;
a.g() ;
System.out.println ("--- dans main") ;
int n=1 ;
long q=12 ;
float x=1.5f ;
double y = 2.5 ;
a.f(n, q) ; // my problem is here
a.f(q, n) ;
a.f(n, x) ;
a.f(n, y) ;
}
Cuando llamo el método a.f(n,q)
en el principal espero un error, sino que llama al método f(int n, float x)
mientras mi q
es un long
número y su tamaño es más grande que un float
's tamaño (8 bytes / 4 bytes) Por eso me pregunto cómo estos tipos de obras primitivas?
Invocaciones de métodos ocupan una longitud bastante trozo de la especificación. En resumen, los ingresos del compilador de la siguiente manera:
- Identificar las clases en la que se podría invocar el método.
- Identificar métodos en aquellas clases que podrían ser invocados.
- Si se identifica más de un método, elegir el más específica.
Paso 2 es la más interesante aquí: esta se desarrolla en una serie de pasos. Para resumir:
- Si hay un no-varargs método en la clase con los tipos de parámetros mismas exactas (estricta de invocación), que elegir.
- Si hay un no-varargs método en la clase con tipos de parámetros para los que las conversiones automáticas de los parámetros reales (invocación suelto), que elegir.
- Si hay una varargs método en la clase con los tipos de parámetro que coinciden con la conversión automática, que elegir.
Que está suministrando parámetros que no coinciden exactamente con cualquiera de los tipos de parámetros de las sobrecargas, por lo que necesita comprobar si se puede convertir que los parámetros para permitir estricta invocación. Las conversiones en las invocaciones estrictas son :
- una conversión de identidad (§5.1.1)
- un ensanchamiento conversión primitiva (§5.1.2)
- un ensanchamiento de conversión de referencia (§5.1.5)
Un int
pueden ser convertidos por conversión identidad a int
. A long
puede ser convertido por la ampliación de conversión primitivo a una float
.
Por lo tanto f(int, float)
es aplicable.
f(long, double)
y f(double, double)
también son aplicables, puesto que int
puede ser ampliado a long
y double
; y long
puede ser ampliado a double
.
Sin embargo, éstos son menos específicas que f(int, float)
, dado que int
se puede ampliar a long
y double
, y float
se pueden ampliar al double
. Por lo tanto, por la intuición informal establecido en JLS Sec 15.12.2.5 , estos métodos son menos específicas que f(int, float)
. Como tal, f(int, float)
es el que se invoca.