1

Consider these two methods:

// All good...
static <T> T extractFirst(T[] arr) {
    if (arr.length > 0) return arr[0];
    return null;
}

// Warning: "possible heap pollution from parameterized vararg type"
static <T> T extractFirstVarargs(T... arr) {
    if (arr.length > 0) return arr[0];
    return null;
}

The compiler gives a warning for the second method, but not for the first method which is just the de-sugared version of it. Why is that?

As far as I understand, I can produce unsafe code whenever I work with array types (since they are covariant due to historical reasons) or raw container types. How varargs factor into this is not clear to me.

EDIT: I know what heap pollution and type erasure is. But I fail to see why the warning is not also present in extractFirst since I can cause heap pollution there as well.

EDIT 2: The warning doesn't even relate to generic params (T), it also appears when using something like List<String>... as a formal param.

domin
  • 1,192
  • 1
  • 7
  • 28
  • 1
    Does this answer your question? [Possible heap pollution via varargs parameter](https://stackoverflow.com/questions/12462079/possible-heap-pollution-via-varargs-parameter) – GreyBeardedGeek Feb 01 '22 at 12:41
  • Also worth reading: https://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.6.3.7, [Java: "Heap pollution"](https://softwareengineering.stackexchange.com/q/155994), https://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html – Pshemo Feb 01 '22 at 12:44
  • Thanks for the pointers. However, I still fail to see why all of that does not apply to `T[]`. Why is the "variable arity" so important if all examples that show unsafe code would be equally unsafe if `T[]` were used as the formal argument type? – domin Feb 01 '22 at 12:48
  • 1
    This may help: https://stackoverflow.com/a/14252221 (especially last example) – Pshemo Feb 01 '22 at 13:40
  • 1
    @Pshemo This is exactly what I was missing! Effectively, a potential generic caller must new-up the implicit array `T[]` without actually knowing T, therefore falling-back to `Object[]`, and that is the actual problem here. ;) – domin Feb 01 '22 at 13:53
  • OK, I just realized that the same warning also appears if the signature looks like this instead: `extractFirstVarargs(List... arr)`, but doesn't appear if de-sugared like this: `extractFirst(List[] arr)` The argument about generic params doesn't apply here though, so what's the explanation in this case? – domin Feb 01 '22 at 17:52

0 Answers0