Java safe coding guide: Heap pollution

Introduction

What is heap pollution? Heap pollution occurs when the object referenced by a parameterized type variable is not an object of the parameterized type.

We know that in JDK5, the concept of generics is introduced. When creating a collection class, we can specify the type of objects that should be stored in the collection class.

If different types are referenced in the set of specified types, then this situation is called heap pollution.

Examples of heap pollution

Some students may ask, since JDK5 introduces generics, why does heap pollution still occur?

This is a good question, let's look at an example:

    public void heapPollution1(){
    
    
        List normalList= Arrays.asList("www.flydean.com",100);
        List<Integer> integerList= normalList;
    }

In the above example, we used Arrays.asList to create an ordinary List.

This List contains two types of int and String. When we assign List to List, the Java compiler will not judge the type in the assigned List. IntegerList contains non-Integer elements, which eventually leads to the use of There will be an error.

Assigning directly to List will not perform type checking, so what if we add elements directly to List?

Let's look at the following example:

    private void addToList(List list, Object object){
    
    
        list.add(object);
    }

    @Test
    public void heapPollution2(){
    
    
        List<Integer> integerList=new ArrayList<>();
        addToList(integerList,"www.flydean.com");
    }

In the above example, we defined an addToList method. The parameter of this method is a normal List, but we passed in a List.

As a result, we found that the list.add method did not perform parameter type verification.

How to modify the above example?

We need to add type check to the List parameter of the addToList method:

    private void addToList(List<Integer> list, Object object){
    
    
        list.add(object);
    }

What if addToList is a very versatile method? It is realistic to add parameter types to the parameters of addToList.

At this time, we can consider using the Collections.checkedList method to convert the input List into a checkedList so that only specific types of elements are received.

    public void heapPollutionRight(){
    
    
        List<Integer> integerList=new ArrayList<>();
        List<Integer> checkedIntegerList= Collections.checkedList(integerList, Integer.class);
        addToList(checkedIntegerList,"www.flydean.com");
    }

Run the above code, we will get the following exception:

java.lang.ClassCastException: Attempt to insert class java.lang.String element into collection with element type class java.lang.Integer

More general example

Above we defined an addToList method, because there is no type judgment, so the problem of heap pollution may occur.

Is there any way that can be used universally while avoiding heap pollution?

Of course, we look at the following implementation:

    private <T> void addToList2(List<T> list, T t) {
    
    
        list.add(t);
    }

    public <T> void heapPollutionRight2(T element){
    
    
        List<T> list = new ArrayList<>();
        addToList2(list,element);
    }

In the above example, we defined a parameter type T in the addToList method. In this way, we ensure the consistency of the element types in the List.

variable parameter

In fact, method parameters can be variable. Let's consider the following example:

    private void addToList3(List<Integer>... listArray){
    
    
        Object[] objectArray = listArray;
        objectArray[0]= Arrays.asList("www.flydean.com");
        for(List<Integer> integerList: listArray){
    
    
            for(Integer element: integerList){
    
    
                System.out.println(element);
            }
        }
    }

In the above example, our parameter is an array of List. Although the element type in the List is fixed, we can re-assign to the parameter array to actually modify the parameter type.

If the method parameters of addToList3 above are modified as follows, there will be no problems:

private void addToList4(List<List<Integer>> listArray){
    
    

In this case, the type of List is fixed, and we cannot modify it by reassigning.

Examples in this article:

learn-java-base-9-to-20/tree/master/security

This article has been included in http://www.flydean.com/java-security-code-line-heap-pollution/

The most popular interpretation, the most profound dry goods, the most concise tutorial, and many tips you don't know are waiting for you to discover!

Welcome to pay attention to my official account: "programs those things", know technology, know you better!

Guess you like

Origin blog.csdn.net/superfjj/article/details/108659731