Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generic class of another generic class

I have a base generic class representing all objects of my model that have an identifier of whatever type:

public abstract class IdObject<T> {
    private T    id;
    public  T    getId()     { return this.id; }
    public  void setId(T id) { this.id = id;   }
}

Then, I have an super-interface representing the DAO for those IdObject objects:

public interface IdObjectDAO<T extends IdObject<U>> {
    public T getObjectById(U id);
}

but I get the compiler error of "U cannot be resolved to a type". If I change the interface definition by:

public interface IdObjectDAO<T extends IdObject<U extends Object>> {...}

I get the compiler error of "Syntax error on token "extends", , expected". The only way to define the interface without compiler errors is:

public interface IdObjectDAO<T extends IdObject<? extends Object>> {...}

but then I don't have a type alias (U) for the public T getObjectId(U id) method. The only solution I've found to solve it is using 2 type parameters:

public interface IdObjectDAO<T extends IdObject<U>, U> {...}

but I want to avoid using those 2 type parameters to avoid specifying the identifier type in model and DAO classes:

public class     Person    extends IdObject<Integer> {...}
public interface PersonDAO extends IdObjectDAO<Person, Integer> {...}
                                                     ^^^^^^^^^ <== avoid this

Can anybody think in another way to implement this generic of generic or define the IdObjectDAO interface?

Thanks in advance!

like image 219
judokaine Avatar asked Jun 12 '14 10:06

judokaine


People also ask

Can a generic class be derived from another generic class?

In the same way, you can derive a generic class from another generic class that derived from a generic interface. You may be tempted to derive just any type of class from it. One of the features of generics is that you can create a class that must implement the functionality of a certain abstract class of your choice.

Can a generic class have multiple generic parameters?

A Generic class can have muliple type parameters.

Can a generic class be a subclass of a non-generic class?

A generic class can extend a non-generic class.

Can we inherit generic class in Java?

It inherits all members defined by super-class and adds its own, unique elements. These uses extends as a keyword to do so. Sometimes generic class acts like super-class or subclass. In Generic Hierarchy, All sub-classes move up any of the parameter types that are essential by super-class of generic in the hierarchy.


1 Answers

An interface is not just defined by its name, it consists of the signatures of all methods defined in it. Since you have the method

public T getObjectById(U id);

your interface is generic in both T and U. There is no way for the interface to determine U from IdObject<U>, so you'll have to specify it explicitly if you want compile time type safety.

If you really insist on only providing T as a generic parameter, the two (pretty bad) workarounds I can come up with are:

1) Lose type safety:

public interface IdObjectDAO<T extends IdObject<?>> {
    public T getObjectById(Object id);
}

If you implement equals of U correctly, you can still successfully call

id.equals(t.getId());

for an object t of type T.

2) Wrap your id in an object of type T:

public interface IdObjectDAO<T extends IdObject<?>> {
    public T getObjectBySample(T sample);
}

You can call this like:

Integer id = 5;
Person sample = new Person(id);
Person object = personDao.getObjectBySample(sample);
like image 77
Vincent van der Weele Avatar answered Sep 18 '22 18:09

Vincent van der Weele