我有界面:
interface Identifable<T extends Serializable> {
T getID();
}
和实现此目的的类:
public class Cat implements Identifable<Long> {
public Long getID(){...};
}
一切正常。至今。现在我想创建GenericDAO,为什么我不能创建它?:
public abstract GenericDAO<T extends Identifable<S>> {
T getByID(S id);
}
我只能声明我的GenericDAO:
public abstract GenericDAO<T extends Identifable, S> {
T getById(S id);
}
完整的课程:
public CatDAO extends GenericDAO<Cat, Long> {
Cat getById(Long id);
}
但我认为这没用,因为我重复了一些信息。我已经声明,Cat实现了Identifable&lt;长&gt;,那为什么我必须声明GenericDAO&lt; Cat,Long&gt;,而不仅仅是GenericDAO&lt;猫&gt; ?
答案 0 :(得分:4)
在Java中,必须指定每种泛型类型。你可以不指定任何类型,但不能只指定一个类型。
此外,必须在声明中指定每个泛型类型。如果您想拥有class GenericDAO<T extends Identifable<U>>
,则必须将U
的泛型类型声明添加到您的类声明中(因为此处U
实际上是通用类型):
public abstract class GenericDAO<T extends Identifable<U>, U>
以下是部分偏离主题,但您可能会发现它很有用。
我注意到在GenericDAO
的定义中,两个泛型类型并不相互关联。这可能不是你想要的。
这里有两个泛型匹配的特定情况(Long
和Cat
定义中的CatDAO
类型)。考虑使用这些声明:
public class Dog implements Identifable<Long>
public class DogDAO extends GenericDao<Dog, String>
这会强制您在getById
方法中编写DogDAO
方法:
Dog getById(String id);
getId
中的Dog
方法会返回Long
,因此您的getById
方法int DogDAO
必须将String
与Long
进行比较{1}}秒。这是有效的事情,但它有点违反直觉。使用getById
DogDAO
方法获取Long
参数更有意义,因为Dog
的ID实际上是Long
s。
如果要将两种类型绑定在一起,可以将GenericDAO
类定义为:
public abstract class GenericDAO<T extends Identifable<S>, S>
您仍然需要指定第二个参数,但至少编译器可以帮助您确保类型匹配。
答案 1 :(得分:0)
试试这个:
public abstract class GenericDAO<S extends Serializable, T extends Identifable<S>> {
abstract T getByID(S id);
}