What are the differences between these two generic statements? They seem to do the same thing and it appears to not have any effect at compile time because I can use them interchangeably with no errors.
class Foo {
}
class FooBar extends Foo {
}
interface FooService {
Set<? extends Foo> getFooObject();
<T extends Foo> Set<T> getFooObjectAlternative();
}
class FooServiceImpl implements FooService {
@Override
Set<FooBar> getFooObject() {
// works
}
@Override
Set<FooBar> getFooObjectAlternative() {
// works but you get a warning
}
@Override
Set<Integer> getFooObjectAlternative() {
// works for some reason!
}
}