我有一个基类泛型类,表示我的模型中具有任何类型标识符的所有对象:
public abstract class IdObject<T> {
private T id;
public T getId() { return this.id; }
public void setId(T id) { this.id = id; }
}
然后,我有一个超级接口代表那些IdObject对象的DAO:
public interface IdObjectDAO<T extends IdObject<U>> {
public T getObjectById(U id);
}
但是我得到编译错误“U无法解析为某种类型”。如果我通过以下方式更改接口定义:
public interface IdObjectDAO<T extends IdObject<U extends Object>> {...}
我得到编译器错误“令牌上的语法错误”扩展“,预期”。定义没有编译器错误的接口的唯一方法是:
public interface IdObjectDAO<T extends IdObject<? extends Object>> {...}
但是我没有public T getObjectId(U id)
方法的类型别名(U)。我发现解决它的唯一解决方案是使用2种类型的参数:
public interface IdObjectDAO<T extends IdObject<U>, U> {...}
但我想避免使用这两个类型参数来避免在模型和DAO类中指定标识符类型:
public class Person extends IdObject<Integer> {...}
public interface PersonDAO extends IdObjectDAO<Person, Integer> {...}
^^^^^^^^^ <== avoid this
任何人都可以用另一种方式来实现这种泛型的通用或定义IdObjectDAO
接口吗?
提前致谢!
答案 0 :(得分:1)
接口不仅仅由其名称定义,它还包含其中定义的所有方法的签名。既然你有方法
public T getObjectById(U id);
您的界面在T
和U
中都是通用的。接口无法从U
确定IdObject<U>
,因此如果您希望编译时类型安全,则必须明确指定它。
如果你真的坚持只提供T
作为通用参数,我可以提出的两个(非常糟糕的)解决方法是:
1)失去类型安全:
public interface IdObjectDAO<T extends IdObject<?>> {
public T getObjectById(Object id);
}
如果您正确实施equals
U
,您仍然可以成功拨打
id.equals(t.getId());
表示t
类型的对象T
。
2)将您的ID包裹在T
类型的对象中:
public interface IdObjectDAO<T extends IdObject<?>> {
public T getObjectBySample(T sample);
}
你可以这样称呼:
Integer id = 5;
Person sample = new Person(id);
Person object = personDao.getObjectBySample(sample);