Operador :: (Double Colon) en Java 8: de principiante a experto
\n\n¿Alguna vez has escrito código en Java 8 y has visto una construcción extraña como System.out::println o String::length? Parece magia, ¿verdad? En realidad, no es magia, sino una de las herramientas más elegantes de Java moderno: el operador de doble dos puntos (también conocido como double colon operator o referencia a método).
En este artículo, analizaremos el operador :: desde lo más básico hasta técnicas avanzadas. Aprenderás a escribir código más limpio, conciso y legible. ¡Vamos allá!
¿Qué es el operador :: y para qué sirve?
\n\nEl operador :: (double colon) se introdujo en Java 8 como azúcar sintáctico para las expresiones lambda. Si una expresión lambda simplemente llama a un método existente, puedes reemplazarla con una referencia a método. Esto hace que el código sea más corto y expresivo.
Compáralo tú mismo:
\n\n// Expresión lambda\nlist.forEach(s -> System.out.println(s));\n\n// Referencia a método (operador ::)\nlist.forEach(System.out::println);\n\nLa segunda opción no solo es más corta, sino que dice de inmediato: "Para cada elemento, llama al método println de System.out". ¡Hermoso!
\n\nCuatro tipos de referencias a métodos
\n\nEn Java 8, existen cuatro tipos principales de method reference. Analicemos cada uno con ejemplos.
\n\n1. Referencia a un método estático
\n\nSintaxis: ClassName::staticMethodName
Ejemplo: contar números pares en una lista.
\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class StaticMethodReference {\n public static boolean isEven(Integer number) {\n return number % 2 == 0;\n }\n\n public static void main(String[] args) {\n List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);\n \n // Lambda\n long countLambda = numbers.stream()\n .filter(n -> StaticMethodReference.isEven(n))\n .count();\n \n // Referencia a método estático\n long countRef = numbers.stream()\n .filter(StaticMethodReference::isEven)\n .count();\n \n System.out.println("Números pares: " + countRef); // 3\n }\n}\n\nObserva: no estamos llamando al método isEven — simplemente pasamos una referencia a él. Java mismo sustituirá cada elemento de la lista como argumento.
2. Referencia a un método de instancia de un objeto específico
\n\nSintaxis: objectReference::instanceMethodName
Este tipo se usa cuando ya tienes un objeto específico y quieres llamar a su método.
\n\nimport java.util.Arrays;\nimport java.util.List;\n\npublic class InstanceMethodReference {\n public static void main(String[] args) {\n List<String> names = Arrays.asList("Ana", "Boris", "Víctor");\n \n // Creamos un objeto StringBuilder\n StringBuilder sb = new StringBuilder("Nombres: ");\n \n // Lambda\n names.forEach(name -> sb.append(name).append(" "));\n \n // Referencia a método de instancia\n // (pero append devuelve StringBuilder, por lo que usamos lambda)\n // Para System.out.println es ideal:\n names.forEach(System.out::println);\n \n System.out.println(sb.toString()); // Nombres: Ana Boris Víctor\n }\n}\n\nEl ejemplo clásico es System.out::println. System.out es un objeto específico de PrintStream, y println es su método.
3. Referencia a un método de instancia de un objeto arbitrario de un tipo particular
\n\nSintaxis: ClassName::instanceMethodName
Este tipo a menudo se confunde con el anterior. Aquí no especificamos un objeto concreto; en su lugar, decimos: "Toma cualquier objeto de esta clase y llama a su método".
\n\nBlogs
Book Recommendations
Leer también
Trabajo con WebAssembly y PHP: de la A a la Z
Pruebas de integración de Go con Docker: nivel avanzado
Cómo invocar una Activity desde otra aplicación en Android: guía completa para Kotlin
Código limpio en C++: cómo escribir para no avergonzarse dentro de un año
Observabilidad en C++: trazado, métricas y logs para profesionales