Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a heap pollution work around?

I have a constructor like below

public MyConstructor(MyObject<T> ... objects) {
     // ...
}

Eclipse warns me with the following message:

Type safety: Potential heap pollution via varargs parameter objects

I change the constructor like this:

public MyConstructor(MyObject<T>[] objects) {
     // ...
}

Now, the warning disappears. However, I think the potential danger is not solved.

Is this workaround valid ?

like image 757
Stephan Avatar asked Jul 15 '14 04:07

Stephan


People also ask

What is heap pollution?

Heap pollution simply implies that you have "bad stuff" in your heap. It is an analogy to (for example) water pollution which is where you have "bad stuff" in the water. Specifically, the bad stuff here is objects of type A where you ought to have objects of type B ... according to the static typing.

How does the compiler detect heap pollution in Java?

Usually, the compiler detects the heap pollution situation at the compile-time only and it throws unchecked warning message. At the run-time, there is a chance of arising heap pollution that will cause ClassCastException.

What are the pollutants of major public health concern?

Pollutants of major public health concern include particulate matter, carbon monoxide, ozone, nitrogen dioxide and sulfur dioxide. Outdoor and indoor air pollution cause respiratory and other diseases and are important sources of morbidity and mortality.

How does air pollution affect our health and climate?

From smog hanging over cities to smoke inside the home, air pollution poses a major threat to health and climate. Ambient (outdoor) air pollution in both cities and rural areas is causing fine particulate matter which result in strokes, heart diseases, lung cancer, acute and chronic respiratory diseases.


2 Answers

In a way it is a workaround. Creating arrays of non-reifiable component type is unsafe. Therefore such array creation expressions are disallowed by the compiler:

// List<String> is erased to List => disallowed
Object example = new List<String>[] { null, null };

// List<?> is effectively reifiable => allowed
Object example = new List<?>[] { null, null };

Yet, hidden array creations via variable arity methods, such as Arrays.asList, are allowed.

// RHS amounts to Arrays.asList(new List<String>[] { null, null })
List<List<String>> example = Arrays.asList(null, null);

Since you disallowed this array creation, your heap can no longer be polluted. But: How are you ever going to call that constructor?

Please note that your constructor may not pollute the heap at all. The only way it does is if

  • it converts the array to a less specifc type (i.e. MyObject<?>[] or Object[]) or
  • it lets the array escape somehow (i.e. assigning it to a field and returning from a getter or passing it to a potentially unsafe method).

If you do neither you can mark the constructor as having @SafeVarargs and the warning goes away.

like image 106
Ben Schulz Avatar answered Oct 01 '22 13:10

Ben Schulz


However, because of type erasure, the compiler converts the varargs formal parameter to Object[] elements. Consequently, there is a possibility of heap pollution.

As we know the reason of this warning mainly based on type erasure now it's clearly stated in Java Docs for Heap Pollution that,

If you ensure that your code compiles without warnings, then no heap pollution can occur.

And More on this

The compiler has already generated a warning when it translated the varargs formal parameter List<String>... l to the formal parameter List[] l. This statement is valid; the variable l has the type List[], which is a subtype of Object[].

So that

Consequently, the compiler does not issue a warning or error if you assign a List object of any type to any array component of the objectArray array.

All quoted statements are copied from Java Doc

like image 20
akash Avatar answered Oct 01 '22 13:10

akash