Java tipo de promoción en los parámetros

riruzen:

Me encontré con este fragmento:

public class ParamTest {
    public static void printSum(int a, double b) {
        System.out.println("In intDBL " + (a + b));
    }

    public static void printSum(long a, long b) {
        System.out.println("In long " + (a + b));
    }

    public static void printSum(double a, long b) {
        System.out.println("In doubleLONG " + (a + b));
    }

    public static void main(String[] args) {
        printSum(1, 2);
    }
}

Esto dará lugar a un error de compilación:

Error: (15, 9) java: referencia a printSum es ambigua tanto método printSum (int, doble) en ParamTest y método printSum (largo, largo) en partido ParamTest

¿Cómo es esta ambigua? no debe sólo el segundo parámetro se promoverá en este caso, ya que el primer parámetro es ya un int? La primera necesidad parámetro no ser promovido en este caso, ¿verdad?

La compilación tiene éxito si actualizo el código para agregar otro método:

public static void printSum(int a, long b) {
    System.out.println(String.format("%s, %s ", a, b));
}

Permítanme ampliar sólo para aclarar. El código siguiente resultado en la ambigüedad:

public class ParamTest {

    public static void printSum(int a, double b) {
        System.out.println("In intDBL " + (a + b));
    }

    public static void printSum(long a, long b) {
        System.out.println("In long " + (a + b));
    }

    public static void main(String[] args) {
        printSum(1, 2);
    }
}

A continuación, este código de abajo también da lugar a la ambigüedad:

public class ParamTest {

    public static void printSum(int a, double b) {
        System.out.println("In intDBL " + (a + b));
    }

    public static void printSum(double a, long b) {
        System.out.println("In doubleLONG " + (a + b));
    }

    public static void main(String[] args) {
        printSum(1, 2);
    }
}

Sin embargo éste no da lugar a la ambigüedad:

public class ParamTest {

    public static void printSum(int a, double b) {
        System.out.println("In intDBL " + (a + b));
    }

    public static void printSum(long a, double b) {
        System.out.println("In longDBL " + (a + b));
    }

    public static void main(String[] args) {
        printSum(1, 2);
    }
}
alboroto :

Creo que esto tiene algo que ver con la regla específica de JLS sobre 15.12.2.5. La elección de la más específica Método . Se afirma que:

Si más de un miembro de método es a la vez accesible y aplicable a una llamada a un método, es necesario elegir uno para proporcionar el descriptor para el envío método en tiempo de ejecución. El lenguaje de programación Java utiliza la regla de que se elige el método más específico.

Cómo Java elige el método más específica se explica con más detalle en el texto:

La intuición informal es que un método es más específico que otro si cualquier invocación manejado por el primer método podría ser transmitida a la otra sin un error en tiempo de compilación. En casos como un argumento escrito explícitamente expresión lambda (§15.27.1) o una invocación variable de aridad (§15.12.2.4), se permite cierta flexibilidad para adaptar una firma a la otra.

En el caso de que su ejemplo, todos los métodos son accesibles y aplicable a la invocación de métodos, por lo tanto, Java tiene que determinar cuál de ellos es más específica .

Para estos métodos, ninguno puede ser determinada para ser más específicos:

public static void printSum(int a, double b) {
    System.out.println("In intDBL " + (a + b));
} // int, double cannot be passed to long, long or double, long without error

public static void printSum(long a, long b) {
    System.out.println("In long " + (a + b));
} // long , long cannot be passed to int, double or double, long without error

public static void printSum(double a, long b) {
    System.out.println("In doubleLONG " + (a + b));
} // double, long cannot be passed to int, double or long, long without error

El cuarto método borra ambigüedad precisamente porque cumple la condición necesaria para ser más específico .

public static void printSum(int a, long b) {
    System.out.println(String.format("%s, %s ", a, b));
}

Es decir, (int, long) se puede pasar a (int, double), (mucho, mucho), o (doble, de longitud) y sin errores de compilación.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=306800&siteId=1
Recomendado
Clasificación