I am experimenting with Java generics. I understand with Java generics we can create class and methods which only deals with specific types. This enable detection of programming error at compile time.
My question may sounds strange. Why use E extends Superclass
instead of Superclass
? Please take a look at the code below.
class Hunter <E extends Animal>{}
class Keaper <Animal>{}
/*edit: as AR.3 and other pointed out, Keaper<Animal> is the same as Keaper<E>.
Animal is just a type parameter here*/
class Animal{}
class Cat extends Animal{}
class Dog extends Animal{}
public class TestGeneric {
public static void main(String[] args) {
Hunter<Cat> hunter1 = new Hunter<>();
Hunter<Dog> hunter2 = new Hunter<>();
Hunter<Animal> hunter3 = new Hunter<>();
ArrayList<Hunter> hunters= new ArrayList<>();
hunters.add(hunter1);
hunters.add(hunter2);
hunters.add(hunter3);
Keaper<Cat> keaper1 = new Keaper<>();
Keaper<Dog> keaper2 = new Keaper<>();
Keaper<Animal> keaper3 = new Keaper<>();
//Edit: as AR.3 and others pointed out, Keaper<String> is also legal here.
ArrayList<Keaper> keapers= new ArrayList<>();
keapers.add(keaper1);
keapers.add(keaper2);
keapers.add(keaper3);
}
}
I feel E extends Animal
is almost the same as Animal
, except the first one may provide more information. Any idea?
Actually Animal
as declared in the definition of the Keaper
class is nothing but a type parameter (it would be more conventional to just use one letter for it, like Keaper<T>
). So it's a completely different range of possible type arguments: the Keaper
class can accept any type as parameter, not just Animal
s. You can write Keaper<String>
and it will compile fine, which is clearly not what you want.
What you intended to do is not possible with generics: you cannot force a class to be generic with only one possible type argument ever associated with it. What you can do is limit the range of associated types to be, for example, any type that extends a certain type, which you already did with the Hunter
class.
Also as mentioned in @JHH's comment, you should avoid using Keaper
as a raw type in a list, otherwise the code would not be fully generic. Instead of ArrayList<Keaper> keapers = new ArrayList<>()
you can write ArrayList<Keaper<? extends Animal>> keapers = new ArrayList<>()
.
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