Reputation: 61
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!
Upvotes: 6
Views: 1499
Reputation: 13177
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);
Upvotes: 1