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.

No hay comentarios.:

Publicar un comentario