I have code in my project that looks like this:
public interface Bar<T extends Foo<?>> {
//...
}
public class MyFoo implements Foo<String> {
private List<Bar<Foo<String>> barFoo = ...
public <U extends Foo<String>> boolean addBar(Bar<? extends U> b) {
barFoo.add((Bar<Foo<String>>) b); //safe cast?
}
}
Eclipse gives a warning for the cast in addBar
that the cast is unsafe. However, am I correct in assuming that the cast will not throw given the restrictions that I have put on the type parameters, and therefore the cast is indeed safe?
Implementing generics into your code can greatly improve its overall quality by preventing unprecedented runtime errors involving data types and typecasting.
In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs.
A generic interface declaration defines a set of types, one for each possible invocation of the type parameter section. All parameterized types share the same interface at runtime. A method is generic if it declares one or more type variables. These type variables are known as the formal type parameters of the method.
Not in general.
Suppose Bar
has a method void get(T value)
, and there are two implementations of Foo<String>
, MyFoo
and YourFoo
. Now suppose a caller calls addBar
on a value of type Bar<MyFoo>
. This works: when U
= Foo<String>
, we have that Bar<MyFoo>
is a subtype of Bar<? extends U>
. Now we cast that value to a Bar<Foo<String>>
.
Now if Bar
has no methods that accept T
's as arguments, there's no problem. But suppose it has a method void process(T value)
. The implementation we called has T
= MyFoo
, so it only has a process(MyFoo value)
method. Once we cast it to a Bar<Foo<String>>
, though, we might call it with a YourFoo
instead. This is illegal.
Stab in the dark, but I suspect that what you really wanted to do was declare barFoo
as a List<? extends Bar<? extends Foo<String>>
.
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