jud*_*ine 6 java generics dao interface
我有一个基本的泛型类,代表我的模型中具有任何类型标识符的所有对象:
public abstract class IdObject<T> {
private T id;
public T getId() { return this.id; }
public void setId(T id) { this.id = id; }
}
Run Code Online (Sandbox Code Playgroud)
然后,我有一个代表 IdObject 对象的 DAO 的超级接口:
public interface IdObjectDAO<T extends IdObject<U>> {
public T getObjectById(U id);
}
Run Code Online (Sandbox Code Playgroud)
但我收到“U 无法解析为类型”的编译器错误。如果我通过以下方式更改接口定义:
public interface IdObjectDAO<T extends IdObject<U extends Object>> {...}
Run Code Online (Sandbox Code Playgroud)
我收到“标记“扩展”,预期的语法错误的编译器错误。在没有编译器错误的情况下定义接口的唯一方法是:
public interface IdObjectDAO<T extends IdObject<? extends Object>> {...}
Run Code Online (Sandbox Code Playgroud)
但是然后我没有该public T getObjectId(U id)方法的类型别名(U)。我发现解决它的唯一解决方案是使用 2 个类型参数:
public interface IdObjectDAO<T extends IdObject<U>, U> {...}
Run Code Online (Sandbox Code Playgroud)
但我想避免使用这两个类型参数来避免在模型和 DAO 类中指定标识符类型:
public class Person extends IdObject<Integer> {...}
public interface PersonDAO extends IdObjectDAO<Person, Integer> {...}
^^^^^^^^^ <== avoid this
Run Code Online (Sandbox Code Playgroud)
任何人都可以用另一种方式来实现这种泛型的泛型或定义IdObjectDAO接口吗?
提前致谢!
接口不仅仅由其名称定义,它还由其中定义的所有方法的签名组成。既然你有方法
public T getObjectById(U id);
Run Code Online (Sandbox Code Playgroud)
您的界面在 和 中都是通用T的U。接口无法确定Ufrom IdObject<U>,因此如果您想要编译时类型安全,则必须显式指定它。
如果您真的坚持只提供T通用参数,我可以想出的两个(非常糟糕的)解决方法是:
1)失去类型安全性:
public interface IdObjectDAO<T extends IdObject<?>> {
public T getObjectById(Object id);
}
Run Code Online (Sandbox Code Playgroud)
equals如果正确实现U,仍然可以成功调用
id.equals(t.getId());
Run Code Online (Sandbox Code Playgroud)
t对于类型为 的对象T。
2)将您的 id 包装在类型的对象中T:
public interface IdObjectDAO<T extends IdObject<?>> {
public T getObjectBySample(T sample);
}
Run Code Online (Sandbox Code Playgroud)
你可以这样称呼它:
Integer id = 5;
Person sample = new Person(id);
Person object = personDao.getObjectBySample(sample);
Run Code Online (Sandbox Code Playgroud)