2017-06-09 32 views
0

我試圖做一個存儲庫接口,我們的業務邏輯可以使用的想法,如果我們決定更改支持存儲庫的數據源,業務邏輯不會被影響。我們有很多客戶會使用這個庫,所以我們已經開始製作一套可以在客戶端重複使用的控制器。這是庫接口:編譯錯誤使用Java的泛型和接口

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); 
} 

這是我有問題的控制器:

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); 
    } 

} 

我試圖創建RepositoryQuery,這是負責處理不僅僅是CRUD操作。下面是該接口:

package //redacted 

import java.util.List; 

public interface RepositoryQuery<T extends Object> { 

    List<T> execute(); 
} 

的想法存在,是每個查詢可以擴展可與setter方法,它需要的參數,擴展接口。然後,每個實現可以擴展查詢接口與它所需要的細節(例如:setJdbcTemplate(...))

在控制器上面雖然行:

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

是一個編譯錯誤,同時我不知道爲什麼。我的方法本質上是有缺陷的,還是我錯過了一些東西?

完全錯誤:

[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) 

而且我的錯誤在Eclipse:enter image description here

編輯: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); 

} 
+0

請發送完整的錯誤消息 –

+1

您不必在類型參數中指定邊界。如果你沒有比'T extends Object'更具體的話,你可以把'T'。 – user2357112

+0

@HovercraftFullOfEels應該在我原來的帖子。我已經添加了它。 –

回答

0

您的問題是,該方法需要一個R和你定義R? extends RepositoryQuery<PointBankBalance>中的repository字段聲明。不確定哪個子類是?引用的,所以編譯器不會讓你使用特定的子類。您可以將該字段設置爲Repository<PointBankBalance, AnotherPointsBalance>的實例,在這種情況下,PendingPointsBalance不會是其query方法的有效參數。

解決這個問題的一種方法是用Repository<PointBankBalance, PendingPointsBalance>代替Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>>

或者你可以通過徹底消除了R參數簡化事情:

public interface Repository<T extends Object> { 

    ... 

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

    List<T> query(T query); 
} 

然後只是Repository<PointBankBalance>取代Repository<PointBankBalance, ? extends RepositoryQuery<PointBankBalance>>