¿Qué es Heap Pollution en Java y cómo resolverlo?

¿Qué es la contaminación por montones?

La contaminación del montón implica que tenemos datos incorrectos en nuestra memoria del montón . En lenguaje Java, la contaminación del montón es una situación que ocurre cuando una variable de tipo parametrizado apunta a un objeto que no es de ese tipo parametrizado.

¿Cómo se detecta la contaminación en pilas?

Por lo general, el compilador detecta la situación de contaminación del montón solo en el momento de la compilación y arroja un mensaje de advertencia no verificado.

En el tiempo de ejecución , existe la posibilidad de que surja contaminación del montón que cause ClassCastException . La contaminación del montón significa los datos incorrectos en la memoria del montón. Aquí, los datos incorrectos son un objeto de tipo X, pero se espera un objeto de tipo Y y arrojará ClassCastException en tiempo de ejecución.

Entendamos la contaminación del montón con el programa:

// Program to illustrate Heap pollution situation
  
import java.util.*;
  
class Geeks {
    public static void main(String[] args)
    {
  
        // Creating a List of type String
        List<String> listOfString = new ArrayList<>();
        listOfString.add("Geeksforgeeks");
  
        // Creating a List of type Integer which holds
        // the reference of a List of type String
        // Here compiler will detect that
        // there is a chance of Heap pollution
        // Compiler will throw an unchecked warning
        // at the compile-time only
        List<Integer> listOfInteger
            = (List<Integer>)(Object)listOfString;
  
        // Here we are trying to access
        // firstElement of listOfInteger which holds
        // the reference of a List of type String
        // and trying to store it into
        // one variable of type Integer
        Integer firstElement
            = listOfInteger.get(0);
        System.out.println(firstElement);
    }
}

Consola de tiempo de compilación:

prog.java:12: warning: [unchecked] unchecked cast
        List listOfInteger = (List)(Object)listOfString;
                                                     ^
  required: List
  found:    Object
1 warning

Producción:

Excepción en el subproceso «principal» java.lang.ClassCastException: java.lang.String no se puede convertir a java.lang.Integer
en Geeks.main (File.java:16)

¿Cómo lidiar con la contaminación del montón?

// Program to illustrate Heap pollution with respect to varargs
  
import java.util.*;
  
class Geeks {
    public static void merge(List<String>... stringList)
    {
        // Here we are an array of type Object holds
        // reference of an array of type List<String>
        Object[] arr = stringList;
        List<Integer> temp = new ArrayList<Integer>();
        temp.add(420);
  
        // Here we are trying to assign temp
        // of type List<Integer> into arr[0]
        // which is of type List<String>
  
        // Here ClassCastException will be thrown
        arr[0] = temp;
  
        String firstEle = stringList[0].get(0);
        System.out.println(firstEle);
    }
  
    // Driver code
    public static void main(String args[])
    {
        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<String> list3 = new ArrayList<>();
        list1.add("Geeks");
        list2.add("for");
        list3.add("geeks");
  
        merge(list1, list2, list3);
    }
}

Consola de tiempo de compilación:

prog.java:4: warning:
 [unchecked] Possible heap pollution from
             parameterized vararg type List
    public static void merge(List... stringList)
                                             ^
prog.java:23: warning:
 [unchecked] unchecked generic array creation
             for varargs parameter of type List[]
        merge(list1, list2, list3);
             ^
2 warnings

Producción:

Exception in thread "main" java.lang.ClassCastException:
 java.lang.Integer cannot be cast to java.lang.String
    at Geeks.merge(File.java:10)
    at Geeks.main(File.java:23)

Nota: si no queremos advertencias en el momento del compilador, podemos usar la anotación @SafeVarargs sobre el método. Si sabemos que el método no contiene ninguna situación de contaminación del montón, puede anotarlo con @SafeVarargs para suprimir la advertencia. No significa que permitirá nuestro código para la contaminación del montón. Significa que si en el código existe la posibilidad de contaminación de Heap, arrojará ClassCastException en el tiempo de ejecución.

¿Cómo prevenir situaciones de contaminación por pilas?

No podemos prevenir situaciones de contaminación de pilas, pero podemos seguir algunas reglas que pueden ayudarnos a prevenir la contaminación de pilas como:

  • No use parámetros varargs con tipos genéricos ni convierta una array de objetos en una array de un tipo genérico.
  • No exponer el parámetro varargs o la array genérica a ningún otro método.

Publicación traducida automáticamente

Artículo escrito por Bishal Kumar Dubey 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 *