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!
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.
A Generic class can have muliple type parameters.
A generic class can extend a non-generic class.
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.
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);
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