Mostrando las entradas con la etiqueta variable arguments. Mostrar todas las entradas
Mostrando las entradas con la etiqueta variable arguments. Mostrar todas las entradas

martes, 26 de noviembre de 2019

Usar y tirar (vargs)

Objetos de un solo uso

Los objetos de un solo uso son comunes y muchas veces no es trivial visualizarlos, pues son creados implícitamente, por ejemplo:

 public static void main(String[] args) {
  test1("a", "b");
  test2("a", "b");
  test3(new String[] { "a", "b" });
 }
 public static void test1(String... args) {
 }
 public static void test2(String arg1, String arg2) {
 }
 public static void test3(String[] args) {
 }

Al de-compilar la función main, utilizando Bytecode Viewer, se obtiene lo siguiente 


Los segmentos L1 y L3, son la invocación del método test1 y el segmento L5 es la invocación del método test3. El código en ambos casos es idéntico, creando un arreglo de cadenas con longitud 2 (iconst_2 y newarray). La implicación es que se crea un arreglo implícitamente, al invocar una función con argumentos variables.

Si el código se modifica, para invocar 2 veces la misma función:

  test1("a", "b");

  test1("a", "b");

El resultado de de-compilar el .class se obtiene lo siguiente:


Donde es posible ver que se crean 2 arreglos distintos, lo cual provoca que el garbage collector sea invocado demasiadas veces.

Para lidiar con el problema algunas herramientas o APIs, evitan utilizar varargs. Por ejemplo Log4j 2, declara múltiples funciones con el mismo nombre, pero que reciben parámetros Object desde el 1 hasta el 9.

Funcionalidades similares, se dan con el foreach o la creación de cadenas.