I need to do the following:
Make a generic interface containing two methods:
T primerContenido();
T ultimoContenido();
Make a Warehouse class that contains a list of boxes. This class must implement this interface. The methods will return the content of the first box and the content of the last box respectively.
For now I have:
package exercise2;
public interface GetElement<T> {
T primerContenido();
T ultimoContenido();
}
package exercise2;
public class Caja<T> {
private T element;
public Caja(T element) {
this.element = element;
}
public T getElement() {
return element;
}
public void setElement(T element) {
this.element = element;
}
}
}
package exercise2;
import java.util.ArrayList;
public class Almacen<T> {
ArrayList<Caja<T>> stock = new ArrayList<Caja<T>>();
public Almacen(T... element) {
for(T e : element) {
stock.add(new Caja<T>(e));
}
}
}
In this part of the code public Almacen(T... element)
the editor shows me the title warning and I don't understand what it means or how to fix it.
type safety: Potential heap pollution via varags parameter element
Can someone give me a hand?
It's not a trivial question, so I'll try to explain it in detail:
Java supports methods with a variable number of parameters, but they must all be of the same type, for example:
Using a variable number of parameters is called varargs (for variable arguments ). Inside this method p is an array (not a List) of
int
, so it can be called in two ways:or also like this:
In your case you have declared the varargs parameter using a generic type. The problem is that arrays don't support generics like a list, so after compiling, the method looks like this:
Also
Integer[]
extendsObject[]
, but not the other way around, you can't transform anObject[]
toInteger[]
(although in each position you save an Integer)Explained this, look at this new example:
In theory this code should work, it does not give compilation errors, but it throws warnings. But when you run it you get the following:
What happened? Well, let's see the "decompiled" Test2.class file :
As we can see, the a has had to be transformed
int
toInteger
work with generics (primitives are not allowed). After this, an array of has been createdObject
with thisInteger
, which is correct becauseInteger
it does extend fromObject
... but when trying to cast aInteger[]
, it has not been possible because aObject[] != Integer[]
.As you can see, it's a very rare case that won't happen to you often, so you can ignore it. If the warning bothers you, you can remove it with the annotation
@SafeVarargs
, which is a way of telling the compiler "I know what I'm doing".Or directly, you can avoid the use of generics in varargs.