问题
I'm reading J. Bloch's effective Java and I got that unchecked casts is never good unless we made sure that the cast is safe. Now, since Java Collection frameworks doesn't provide us with Tree
data structure I have to write on my own.
public interface TreeVisitor<E, R> {
public R visit(E leaf);
public R visit(E val, Tree<E>... subtrees);
}
public abstract class Tree<E> {
public abstract <R> R accept(TreeVisitor<E, R> visitor);
public Tree<E> leaf(E leaf) {
return new Tree<E>() {
@Override
public <R> R accept(TreeVisitor<E, R> visitor) {
return visitor.visit(leaf);
}
};
}
public Tree<E> branch(E value, Tree<E>... subtrees){ //1
return new Tree<E>(){
@Override
public <R> R accept(TreeVisitor<E, R> visitor) {
return visitor.visit(value, subtrees);
}
};
}
}
At //1
, I got the warning:
Type safety: Potential heap pollution via varargs parameter subtrees
How can I check that my code actually safe?
回答1:
How can I check that my code actually safe?
It's safe if the visitors only rely on the fact that the elements of subtrees
are Tree<E>
, and do not rely on the fact that subtrees
is Tree<E>[]
. If that is the case, then you should annotate the visit
method with @SafeVarargs
.
回答2:
This Java Tutorial about Generics and Non-Reifiable Types covers your question
Heap pollution occurs when a variable of a parameterized type refers to an object that is not of that parameterized type
When the compiler encounters a varargs method, it translates the varargs formal parameter into an array. However, the Java programming language does not permit the creation of arrays of parameterized types. In the method ArrayBuilder.addToList, the compiler translates the varargs formal parameter T... elements to the formal parameter T[] elements, an array. However, because of type erasure, the compiler converts the varargs formal parameter to Object[] elements. Consequently, there is a possibility of heap pollution.
来源:https://stackoverflow.com/questions/31357422/type-safety-potential-heap-pollution-via-varargs-parameter-subtrees