Java泛型,需要解释

时间:2013-12-09 07:43:44

标签: java generics

有几个简单的测试用例类:

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>>,这可以解决问题,但我不想,我想了解为什么我不能在这里使用方法级泛型。

2 个答案:

答案 0 :(得分:2)

您获得的错误与泛型无关,因为您使用除接口强制之外的其他类型实现该方法。

Editor接口定义

List<T> listObjectsTest1(ListCriteria<T> criteria);

因此UserEditor必须在您的情况下实施

public List<User> listObjectsTest1(ListCriteria<User> criteria) {

您不应该将参数的类型与参数的泛型类型混淆。 Editor界面强制实施ListCriteria类型。 ListCriteria的泛型类型为TT可以由子类绑定,例如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)

  1. listObjectsTest1(UserListCriteria criteria) UserEditor函数未覆盖listObjectsTest1(ListCriteria<T> criteria)接口的函数Editor<T>,因为它们有两个不同的签名,即基本上是参数类型。

  2. listObjectsTest2界面中声明的<L extends ListCriteria<T>> List<T> listObjectsTest2(L criteria);同样如此,但您已在UserEditor类中将其声明为:List<User> listObjectsTest2(UserListCriteria criteria)

  3. 因此您需要将签名更改为:

    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了解更多详情。