简体   繁体   English

使用Java泛型和接口的编译错误

[英]Compilation error using Java generics and interfaces

I'm attempting to make a Repository interface, that our business logic can use, with the idea that if we decide to change the data source that backs the repositories, that the business logic would not be affected. 我试图创建一个存储库接口,以供我们的业务逻辑使用,其想法是,如果我们决定更改支持该存储库的数据源,那么该业务逻辑将不会受到影响。 We have many clients that would be using this library, so we have begun making a suite of controllers that can be reused among clients. 我们有许多客户端将使用此库,因此我们已经开始制作一套可以在客户端之间重用的控制器。 This is the repository interface: 这是存储库接口:

package //redacted

import java.util.Collection;
import java.util.List;

public interface Repository<T extends Object, R extends RepositoryQuery<T>> {

  T add(T entity);

  Collection<T> add(Collection<T> entities);

  void remove(T entity);

  Collection<T> getAll();

  T get(Integer id) throws InvalidEntryException;

  List<T> get(Collection<Integer> ids);

  List<T> query(R query);

  List<T> query(T query);
}

This is the controller I'm having problems with: 这是我遇到问题的控制器:

package //redacted

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import /* redacted */.entities.pointbank.PointBankBalance;
import /* redacted */.entities.user.User;
import /* redacted */.queries.PendingPointsBalance;
import /* redacted */.repository.Repository;
import /* redacted */.repository.RepositoryQuery;

public class RetrievePendingPointBalance { 

  private Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> repository;
  private Constructor<? extends PendingPointsBalance> pendingQuery;

  public RetrievePendingPointBalance(Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> repository,
          Constructor<? extends PendingPointsBalance> pendingQuery) {
    this.repository = repository;
    this.pendingQuery = pendingQuery;
  }

  public PointBankBalance execute(User user) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
      PendingPointsBalance query = pendingQuery.newInstance();
      query.setUser(user);
      return repository.query(query).get(0);
  }

}

I'm trying to create RepositoryQuery, which is what will be responsible for handling more than just CRUD operations. 我正在尝试创建RepositoryQuery,它将负责处理不仅仅是CRUD操作的内容。 Here is the interface for that: 这是该界面:

package //redacted

import java.util.List;

public interface RepositoryQuery<T extends Object> {

    List<T> execute();
}

The idea there, is that each query can extend can extend the interface with setters for the parameters it will need. 那里的想法是,每个查询都可以扩展,可以使用需要它的参数的setter扩展接口。 Then each implementation can extend that query interface with specifics of what it will need (example: setJdbcTemplate(...) ) 然后,每个实现都可以使用需要的细节扩展该查询接口(例如:setJdbcTemplate(...))

On the controller above though, the line: 在上面的控制器上,该行:

      return repository.query(query).get(0);

is a compilation error, and I do not know why. 是编译错误,我不知道为什么。 Is my approach inherently flawed, or am I just missing something? 我的方法天生就有缺陷,还是我只是缺少一些东西?

Full Error: 完全错误:

[ERROR] /Users/redacted/src/main/java/com/redacted/controllers/RetrievePendingPointBalance.java:[26,28] no suitable method found for query(com.redacted.queries.PendingPointsBalance)
    method com.redated.repository.Repository.query(capture#1 of ? extends com.redated.repository.RepositoryQuery<com.redacted.entities.pointbank.PointBankBalance>) is not applicable
      (argument mismatch; com.redacted.queries.PendingPointsBalance cannot be converted to capture#1 of ? extends com.redacted.repository.RepositoryQuery<com.redacted.entities.pointbank.PointBankBalance>)
    method com.redacted.repository.Repository.query(com.redacted.entities.pointbank.PointBankBalance) is not applicable
      (argument mismatch; com.redacted.queries.PendingPointsBalance cannot be converted to com.redacted.entities.pointbank.PointBankBalance)

And my error from Eclipse: 和我从Eclipse错误: 在此处输入图片说明

Edit: PointBankBalance interface 编辑:PointBankBalance界面

package //redacted

import com./* redacted */.entities.pointbank.PointBankBalance;
import com./* redacted */.entities.user.User;
import com./* redacted */.repository.RepositoryQuery;

public interface PendingPointsBalance extends RepositoryQuery<PointBankBalance> {

    void setUser(User user);

}

Your problem is that the method takes an R and you defined R as ? extends RepositoryQuery<PointBankBalance> 您的问题是该方法采用R且您将R定义为? extends RepositoryQuery<PointBankBalance> ? extends RepositoryQuery<PointBankBalance> in the repository field declaration. repository字段声明中? extends RepositoryQuery<PointBankBalance> It's uncertain which subclass ? 不确定哪个子类? refers to, so the compiler won't let you use a specific one. 是指,因此编译器将不允许您使用特定的编译器。 You could potentially set that field to an instance of Repository<PointBankBalance, AnotherPointsBalance> , in which case PendingPointsBalance wouldn't be a valid argument to its query method. 您可以将该字段设置为Repository<PointBankBalance, AnotherPointsBalance>的实例,在这种情况下, PendingPointsBalance对其query方法不是有效的参数。

One way to fix it would be replacing Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> 解决该问题的一种方法是替换Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> with Repository<PointBankBalance, PendingPointsBalance> . Repository<PointBankBalance, PendingPointsBalance> Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>>

Or you could simplify things by removing the R parameter entirely: 或者,您可以通过完全删除R参数来简化事情:

public interface Repository<T extends Object> {

    ...

    List<T> query(RepositoryQuery<T> query);

    List<T> query(T query);
}

Then just replace Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> 然后只需替换Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>> with Repository<PointBankBalance> . Repository<PointBankBalance> Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM