Can someone explain the following behavior to me?
I have a list of X
and use the addAll()
method to add elements. These elements are returned by a method using generic types. Method getA()
returns < T extends A >
with A
being a class. Method getI()
returns < T extends I >
with I
being an interface (see code below).
Difference: with listX.addAll(getA())
I get a compile error (as expected), but listX.addAll(getI())
compiles (throws a runtime error when element is cast to X
).
Simpified code:
interface I {}
class A implements I {}
class X {}
public void test() {
List<X> listX = new ArrayList<>();
listX.addAll(getA());
listX.addAll(getI());
for (X x : listX) {}
}
public <T extends A> List<T> getA() {
return new ArrayList<>();
}
public <T extends I> List<T> getI() {
return new ArrayList<>();
}
Am I missing something? Shouldn't I get a compile error both times?
That behavior seems to be new with Java 8, with versions below I have gotten compiler errors in both cases.
Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.
I'd like to simplify the question and Shmosel's answer as follows:
interface I {}
class A implements I {}
class X {}
public void test() {
X temp = getI(); // compiles
X temp2 = getA(); // does not compile
}
public <T extends I> T getI() {
return null;
}
public <T extends A> T getA() {
return null;
}
getI() can potentially return something that extends X and implements I, which is why it compiles. Normally, the type it actually returns would depend on something, for example an argument passed into the function.
getA() cannot return something that is an X, since it returns something that extends A, which does not extend X.
listX.addAll(getA());
doesn't compile because there's no possible subclass of X
that's also a subclass of A
.
listX.addAll(getI());
does compile because there could be a subclass of X
that also implements I
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With