有几个简单的测试用例类:
public interface ListCriteria<T> {
// some stuff here
}
public class UserListCriteria implements ListCriteria<User> {
// implementation
}
public interface Editor<T> {
// sample method 1
List<T> listObjectsTest1(ListCriteria<T> criteria);
// sample method 2
<L extends ListCriteria<T>> List<T> listObjectsTest2(L criteria);
}
还有一个Editor
的实现,Java认为它没有为这两个示例方法提供必要的实现:
public class UserEditor implements Editor<User> {
@Override
public List<User> listObjectsTest1(UserListCriteria criteria) {
//
}
@Override
public List<User> listObjectsTest2(UserListCriteria criteria) {
//
}
}
两种方法实现都是错误的。问题是为什么。特别是对于后一种方法。
当然我可以interface Editor<T, L extends ListCriteria<T>>
,这可以解决问题,但我不想,我想了解为什么我不能在这里使用方法级泛型。
答案 0 :(得分:2)
您获得的错误与泛型无关,因为您使用除接口强制之外的其他类型实现该方法。
Editor
接口定义
List<T> listObjectsTest1(ListCriteria<T> criteria);
因此UserEditor
必须在您的情况下实施
public List<User> listObjectsTest1(ListCriteria<User> criteria) {
您不应该将参数的类型与参数的泛型类型混淆。 Editor
界面强制实施ListCriteria
类型。 ListCriteria
的泛型类型为T
,T
可以由子类绑定,例如implements ListCriteria<User>
。这就是我的意思,当我说“你得到的错误与泛型无关”时。
我想你想要的是
public interface Editor<C, T extends ListCriteria<C>> {
List<C> listObjectsTest1(T criteria);
}
然后UserEditor可以实现为
public class UserEditor implements Editor<User, UserListCriteria> {
public List<User> listObjectsTest1(UserListCriteria criteria) {
return null;
}
}
<强>为什么呢?特别是对于后一种方法
Editor
界面中的第二种方法
<L extends ListCriteria<T>> List<T> listObjectsTest2(L criteria);
并不意味着您可以实现L
的任何类型绑定
UserEditor
仍必须实施
public <L extends ListCriteria<User>> List<User> listObjectsTest2(L criteria) {
return null;
}
此方法定义将在客户端调用方法时绑定的泛型类型L
。
因此,您可以使用ListCriteria<User>
的子类型的任何类型调用该方法。
答案 1 :(得分:1)
listObjectsTest1(UserListCriteria criteria)
UserEditor
函数未覆盖listObjectsTest1(ListCriteria<T> criteria)
接口的函数Editor<T>
,因为它们有两个不同的签名,即基本上是参数类型。
在listObjectsTest2
界面中声明的<L extends ListCriteria<T>> List<T> listObjectsTest2(L criteria);
同样如此,但您已在UserEditor
类中将其声明为:List<User> listObjectsTest2(UserListCriteria criteria)
因此您需要将签名更改为:
class UserEditor implements Editor<User> {
@Override
public List<User> listObjectsTest1(ListCriteria<User> criteria) {
}
@Override
public <L extends ListCriteria<User>> List<User> listObjectsTest2(L criteria) {
}
}
请仔细阅读jls 8.4.8. Inheritance, Overriding, and Hiding了解更多详情。