Sobrecarga de métodos y ambigüedad en Varargs en Java

Requisito previo: Varargs , sobrecarga de métodos

Sobrecarga de métodos en Varargs

La sobrecarga permite que diferentes métodos tengan el mismo nombre, pero diferentes firmas donde la firma puede diferir por el número de parámetros de entrada o el tipo de parámetros de entrada o ambos. Podemos sobrecargar un método que toma un argumento de longitud variable de las siguientes maneras:

  • Caso 1: métodos con solo parámetros Varargs: en este caso, Java usa la diferencia de tipo para determinar qué método sobrecargado llamar. Si la firma de un método es estrictamente más específica que la otra, Java la elige sin error.

    //Java program to illustrate 
    //method overloading in varargs
    public class varargsDemo
    {
        public static void main(String[] args)
        {
            fun();
        }
      
        //varargs method with float datatype
        static void fun(float... x)
        {
            System.out.println("float varargs");
        }
          
        //varargs method with int datatype
        static void fun(int... x)
        {
            System.out.println("int varargs");
        }
          
        //varargs method with double datatype
        static void fun(double... x)
        {
            System.out.println("double varargs");
        }
    }

    Producción:

    int varargs
    

    Esta salida se debe al hecho de que int es más específico que double. Como se especifica en la sección 15.12.2.5 de JLS, si más de un método miembro es accesible y aplicable a la invocación de un método, es necesario elegir uno para proporcionar el descriptor para el envío del 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 según el tipo de promoción . Las siguientes reglas definen la relación directa de supertipo entre los tipos primitivos en este caso:

    • doble > flotar
    • flotar > largo
    • largo > int
    • int > carácter
    • int > corto
    • corto > byte
  • Caso 2: métodos con Varargs junto con otros parámetros En este caso, Java utiliza tanto el número de argumentos como el tipo de argumentos para determinar a qué método llamar.

    A continuación se muestra el programa java que sobrecarga el método fun() tres veces:

    // Java program to demonstrate Varargs 
    // and overloading.
    class Test 
    {
        // A method that takes varargs(here integers).
        static void fun(int ... a) 
        {
            System.out.print("fun(int ...): " +
                    "Number of args: " + a.length +
                    " Contents: ");
              
            // using for each loop to display contents of a
            for(int x : a)
                System.out.print(x + " ");
              
            System.out.println();
        }
          
        // A method that takes varargs(here booleans).
        static void fun(boolean ... a)
        {
            System.out.print("fun(boolean ...) " +
                    "Number of args: " + a.length +
                    " Contents: ");
              
            // using for each loop to display contents of a
            for(boolean x : a)
                System.out.print(x + " ");
              
            System.out.println();
        }
          
        // A method takes string as a argument followed by varargs(here integers).
        static void fun(String msg, int ... a) 
        {
            System.out.print("fun(String, int ...): " +
                    msg + a.length +
                    " Contents: ");
              
            // using for each loop to display contents of a
            for(int x : a)
                System.out.print(x + " ");
              
            System.out.println();
        }
          
        public static void main(String args[])
        {
            // Calling overloaded fun() with different  parameter
            fun(1, 2, 3);
            fun("Testing: ", 10, 20);
            fun(true, false, false);
        }
    }

    Producción:

    fun(int ...): Number of args: 3 Contents: 1 2 3 
    fun(String, int ...): Testing: 2 Contents: 10 20 
    fun(boolean ...) Number of args: 3 Contents: true false false 
    

Varargs y ambigüedad

A veces pueden producirse errores inesperados al sobrecargar un método que toma un argumento de longitud variable. Estos errores implican ambigüedad porque ambos métodos son candidatos válidos para la invocación. El compilador no puede decidir a qué método vincular la llamada al método.

// Java program to illustrate Varargs and ambiguity
class Test 
{
    // A method that takes varargs(here integers).
    static void fun(int ... a) 
    {
        System.out.print("fun(int ...): " +
                "Number of args: " + a.length +
                " Contents: ");
          
        // using for each loop to display contents of a
        for(int x : a)
            System.out.print(x + " ");
          
        System.out.println();
    }
      
    // A method that takes varargs(here booleans).
    static void fun(boolean ... a)
    {
        System.out.print("fun(boolean ...) " +
                "Number of args: " + a.length +
                " Contents: ");
          
        // using for each loop to display contents of a
        for(boolean x : a)
            System.out.print(x + " ");
          
        System.out.println();
    }
      
    public static void main(String args[])
    {
        // Calling overloaded fun() with different  parameter
        fun(1, 2, 3); //OK
        fun(true, false, false); //OK
        fun(); // Error: Ambiguous!
    }
}

En el programa anterior, la sobrecarga de fun() es perfectamente correcta. Sin embargo, este programa no se compilará debido a la siguiente llamada:

fun(); // Error: Ambiguous!

De acuerdo con (JLS 15.2.2 ), se utilizan 3 fases en la resolución de sobrecarga: la primera fase realiza la resolución de sobrecarga sin permitir la conversión de boxing o unboxing, la segunda fase realiza la resolución de sobrecarga mientras permite el boxing y unboxing y la tercera fase permite combinar la sobrecarga con variable Métodos de aridad, boxing y unboxing. Si no se encuentra ningún método aplicable durante estas fases, se produce ambigüedad.
La llamada anterior podría traducirse en una llamada a fun(int…) o fun(boolean…). Ambos son igualmente válidos y no se resuelven después de las tres fases de resolución de sobrecarga porque ambos tipos de datos son diferentes. Por lo tanto, la convocatoria es inherentemente ambigua.

Otro ejemplo de ambigüedad:
las siguientes versiones sobrecargadas de fun() son inherentemente ambiguas:

static void fun(int ... a) { // method body  }
static void fun(int n, int ... a) { //method body }

Aquí, aunque las listas de parámetros de fun() difieren, no hay forma de que el compilador resuelva la siguiente llamada:

fun(1)

Esta llamada puede resolverse en el método fun(int … a) o fun(int n, int … a), creando así ambigüedad. Para resolver estos errores de ambigüedad como los anteriores, necesitaremos renunciar a la sobrecarga y simplemente usar dos nombres de métodos diferentes.

Este artículo es una contribución de Gaurav Miglani . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *