Java Generic another generic

I have an interface:

interface Identifable<T extends Serializable> { T getID(); } 

and a class that implement this:

 public class Cat implements Identifable<Long> { public Long getID(){...}; } 

everything is working fine. so far. Now I want to create a GenericDAO, why can't I create this ?:

 public abstract GenericDAO<T extends Identifable<S>> { T getByID(S id); } 

I can declare my GenericDAO as follows:

 public abstract GenericDAO<T extends Identifable, S> { T getById(S id); } 

And the full class:

 public CatDAO extends GenericDAO<Cat, Long> { Cat getById(Long id); } 

But I consider it useless because I repeat the information. I already stated that Cat implements Identifable <Long>, so why should I declare GenericDAO <Cat, Long>, and not just GenericDAO <Cat>?

+7
java generics dao
source share
2 answers

In Java, each generic type must be specified. You can go without specifying any type, but you cannot go without specifying only one.

In addition, each generic type must be specified in the declaration. If you want to have the class GenericDAO<T extends Identifable<U>> , you must add a generic type declaration for U to your class declaration similar to this (since U is actually a generic type):

 public abstract class GenericDAO<T extends Identifable<U>, U> 

The part below is off topic, but you may find it useful.

I noticed that in your definition of GenericDAO two common types are not tied to each other. Perhaps this is not what you want.

Here you have a special case when two generics coincide ( Long type in Cat and CatDAO ). Consider the following declarations:

 public class Dog implements Identifable<Long> public class DogDAO extends GenericDao<Dog, String> 

This will force you to write the getById method in the DogDAO method:

 Dog getById(String id); 

Your getId method in Dog returns a Long , so your getById int DogDAO method will have to compare String with Long s. It is really important, but it is a little contrary to intuition. Having a getById method for DogDAO that accepts a Long parameter makes more sense, since Dog identifiers are actually Long s.

If you want to bind the two types together, you can define the GenericDAO class as follows:

 public abstract class GenericDAO<T extends Identifable<S>, S> 

You still need to specify the second parameter, but at least the compiler can help you make sure the types match.

+4
source share

Try the following:

 public abstract class GenericDAO<S extends Serializable, T extends Identifable<S>> { abstract T getByID(S id); } 
0
source share

All Articles