簡體   English   中英

Java 7泛型:如何訪問泛型類型的方法?

[英]Java 7 Generic: How to access method of generic type?

我正在使用Java 7的舊應用程序上工作。我有一個通用的Request類(注釋來自lombok):

@AllArgsConstructor
@Getter
public class Request<T> {
    int Id;
    T requestContext;
}

這是requestContext類型之一:

@AllArgsConstructor
@Getter
public class StudentRequestContext {
    int ID;
    String name;
}

我有一個ResponseGenerator接口:

public interface ResponseGenerator {
    <T> Response getResponse(Request<T> request);
}

這是此接口的實現者類:

public class StudentResponseGenerator implements ResponseGenerator {
    @Override
    public <StudentRequestContext> Response getResponse(
        Request<StudentRequestContext> studentRequest) {
        StudentRequestContext studentRequestContext = 
          (StudentRequestContext) studentRequest.getRequestContext();
        studentRequestContext.get //NO getName METHOD IS AVAILABLE 
    }
}

如上面的代碼注釋所示,StudentResponseGenerator類中的通用類型StudentRequestContext對象沒有可用的吸氣劑。 我想念什么?

public <StudentRequestContext> Response getResponse(...表示您將StudentRequestContext聲明StudentRequestContext所基於的類型變量 。它與上面的名為StudentRequestContext的類完全無關。當您在方法內部使用類型為StudentRequestContext ,它是在引用為此方法聲明的類型變量,而不是類中的類型。

為避免混淆,您可以將類型變量重命名為U ,這與上面的內容完全等效:

public <U> Response getResponse(
    Request<U> studentRequest) {
    U studentRequestContext = 
      (U) studentRequest.getRequestContext();
    studentRequestContext.get //NO getName METHOD IS AVAILABLE 
}

看看是什么問題? 變量studentRequestContext類型為UstudentRequestContext的類型變量),沒有名為getName

簽名<T> Response getResponse(Request<T> request); 意味着與您可能想要的有所不同。 簽名<T> Response getResponse(Request<T> request); 意味着實現方法必須接受任何類型參數的Request類型的參數(您可以等效地將簽名寫為Response getResponse(Request<?> request); )。

您可能想要的是使接口通用,並使它的getResponse方法接受特定類型參數Request的參數,該參數與ResponseGenerator本身的類型參數相同:

public interface ResponseGenerator<T> {
    Response getResponse(Request<T> request);
}

然后,您的StudentResponseGenerator類可以使用特定類型作為type參數來實現該接口:

public class StudentResponseGenerator implements ResponseGenerator<StudentRequestContext> {
    @Override
    public Response getResponse(Request<StudentRequestContext> studentRequest) {
        // ...
    }
}

只是為了讓您了解

<T> Response getResponse(Request<T> request)
 ^    ^ 
 |     actual return type of the method
 type used with the 'request' parameter, needed to type bind args which are generic

所以實現應該看起來像

public class StudentResponseGenerator implements ResponseGenerator {

    @Override
    public Response getResponse(
        Request<StudentRequestContext> studentRequest) { // this is where the T is inferred
        StudentRequestContext studentRequestContext = 
          (StudentRequestContext) studentRequest.getRequestContext();
        return Response.entity(studentRequestContext.getName()).build(); 
    }

}

注意 :我尚未編譯當前構建Response的確切語法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM