7

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 ?

Stephan
  • 41,764
  • 65
  • 238
  • 329

2 Answers2

6

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.

Ben Schulz
  • 6,101
  • 1
  • 19
  • 15
2

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

akash
  • 22,664
  • 11
  • 59
  • 87