[java] Contaminación de montón potencial a través del parámetro varargs


Answers

Cuando declaras

public static <T> void foo(List<T>... bar) el compilador lo convierte en

public static <T> void foo(List<T>[] bar) luego a

public static <T> void foo(List[] bar)

Entonces surge el peligro de que asigne erróneamente valores incorrectos a la lista y el compilador no active ningún error. Por ejemplo, si T es una String , el siguiente código se compilará sin error pero fallará en el tiempo de ejecución:

// First, strip away the array type (arrays allow this kind of upcasting)
Object[] objectArray = bar;

// Next, insert an element with an incorrect type into the array
objectArray[0] = Arrays.asList(new Integer(42));

// Finally, try accessing the original array. A runtime error will occur
// (ClassCastException due to a casting from Integer to String)
T firstElement = bar[0].get(0);

Si revisó el método para asegurarse de que no contiene tales vulnerabilidades, puede anotarlo con @SafeVarargs para suprimir la advertencia. Para las interfaces, use @SuppressWarnings("unchecked") .

Si obtiene este mensaje de error:

El método de Varargs podría causar contaminación acumulativa del parámetro varargs no reificable

y está seguro de que su uso es seguro, debería usar @SuppressWarnings("varargs") lugar. Consulte ¿Es @SafeVarargs una anotación adecuada para este método? y https://stackoverflow.com/a/14252221/14731 para una buena explicación de este segundo tipo de error.

Referencias

Question

Entiendo que esto ocurre con Java 7 cuando se usan varargs con un tipo genérico;

Pero mi pregunta es ...

¿Qué quiere decir exactamente Eclipse cuando dice que "su uso podría potencialmente contaminar el montón"?

Y

¿Cómo es que la nueva anotación @SafeVarargs evita esto?




Cuando utiliza varargs, puede dar como resultado la creación de un Object[] para contener los argumentos.

Debido al análisis de escape, el JIT puede optimizar esta creación de matriz. (Una de las pocas veces que he encontrado que lo hace) No está garantizado que se optimice, pero no me preocuparía a menos que veas que es un problema en tu perfil de memoria.

AFAIK @SafeVarargs suprime una advertencia del compilador y no cambia el comportamiento del JIT.




Related