我有一个基本泛型类,代表我的模型的所有对象,这些对象具有任何类型的标识符:
public abstract class IdObject<T> {
private T id;
public T getId() { return this.id; }
public void setId(T id) { this.id = id; }
}
然后,我有一个 super 接口(interface)代表那些 IdObject 对象的 DAO:
public interface IdObjectDAO<T extends IdObject<U>> {
public T getObjectById(U id);
}
但我得到“U cannot be resolved to a type”的编译器错误。如果我通过以下方式更改接口(interface)定义:
public interface IdObjectDAO<T extends IdObject<U extends Object>> {...}
我收到编译器错误“ token “扩展”上的语法错误”,预期”。在没有编译器错误的情况下定义接口(interface)的唯一方法是:
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
接口(interface)吗?
提前致谢!
最佳答案
接口(interface)不仅由其名称定义,它还包含其中定义的所有方法的签名。既然你有方法
public T getObjectById(U id);
您的界面在 T
中都是通用的和 U
.接口(interface)没办法判断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);
关于另一个泛型类的Java泛型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24182074/