Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 1.7 varargs function reported as unchecked warning

We use some varargs functions and as we move to java 1.7 we are getting a strange unchecked warning.

Function add in interface ICache

public interface ICache<O> {
    void add(Object source, O... objects);
}

in an interface reports the error.

ICache.java:18: warning: [unchecked] Possible heap pollution from parameterized vararg type O
    void add(Object source, O... objects);
  where O is a type-variable:
    O extends Object declared in interface ICache
1 warning

O extends Object, as its generic cache class.

I read the xlint warnings and we do compile with unchecked on, but http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#xlintwarnings seems to imply that this error should be a [varargs] type not an unchecked type.

Am I missing something?

like image 689
Neil Wightman Avatar asked Jun 25 '12 08:06

Neil Wightman


1 Answers

Heap pollution is a term that refers to a type that is pointing to an object that it is not the supertype of when using varargs with a generic type. It occurs when a variable of a parameterized type refers to an object that is not of that parameterized type. This post on stack overflow explains to you exactly what this means and what you should do about it, and gives details on the @SafeVarargs annotation. So, in interface ICache, vararg type O is pointing to Object in your interface, but O is not the supertype of Object, and this generates a heap pollution warning. Notice how it says possible heap pollution. If your code is not causing any problems such as leading to a ClassCastException, it will probably be safe and not pollute the heap, but the compiler has no way of proving this and cannot verify the correctness of the operation, so it will still generate the warning. That is actually the definition of an unchecked warning: when the correctness of an operation involving a parameterized type cannot be verified. See this Oracle page on non-reifiable types for more information. If you don't want to get this warning, you can prevent it with SafeVarargs, or simply suppress it by adding @SuppressWarnings ({"unchecked", "varargs"}) to the method declaration, but you will not get the warning in the event that the method is indeed unsafe.

like image 107
Santiago Benoit Avatar answered Nov 14 '22 17:11

Santiago Benoit