Java Generic of Another generic
I have an interface:
interface Identifable<T extends Serializable> { T getID(); }
And the class that implements this:
public class Cat implements Identifable<Long> { public Long getID(){...}; }
business as usual. So far Now I want to create genericdao, why can't I create it?:
public abstract GenericDAO<T extends Identifable<S>> { T getByID(S id); }
I can only declare my genericdao:
public abstract GenericDAO<T extends Identifable,S> { T getById(S id); }
Complete course:
public CatDAO extends GenericDAO<Cat,Long> { Cat getById(Long id); }
But I think it's useless because I repeat the information I have stated that cat implements identifiable < < long >, so why do I have to declare genericdao < < cat, long >, not just genericdao < < cat >?
Solution
In Java, each generic type must be specified You can specify no type, but you can't specify only one type
In addition, each generic type must be specified in the declaration If you want the class genericdao < T extensions identifiable < U > >, you must add the generic type declaration of u to your class declaration (because u is actually a generic type):
public abstract class GenericDAO<T extends Identifable<U>,U>
The following is a partial digression, but you may find it useful
I noticed that in the definition of genericdao, the two generic types are not related to each other This may not be what you want
Here you have two special cases of generic matching (long type in cat and catdao definitions) Consider these statements:
public class Dog implements Identifable<Long> public class DogDAO extends GenericDao<Dog,String>
This forces you to write the getbyid method in the dogdao method:
Dog getById(String id);
The getid method in dog returns a long, so your getbyid method must compare strings with long in dogdao This is a valid thing, but it's a little counterintuitive It makes more sense to use dogdao's getbyid method to get the long parameter, because dogs ID is actually long
If you want to bind the two types together, you can define the genericdao class as:
public abstract class GenericDAO<T extends Identifable<S>,S>
You still have to specify the second parameter, but at least the compiler can help you ensure that the types match