Java 7 Generic:如何访问泛型类型的方法?

问题描述 投票:0回答:2

我正在使用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对象没有可用的getter。我错过了什么?

java generics java-7
2个回答
1
投票

public <StudentRequestContext> Response getResponse(...表示您将StudentRequestContext声明为此方法通用的类型变量。它与上面名为StudentRequestContext的类完全无关。在方法中使用类型StudentRequestContext时,它指的是为此方法声明的此类型变量,而不是类中的类型。

为避免混淆,您可以将类型变量重命名为U,这与上面的内容完全等效:

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

看看问题是什么?变量studentRequestContext具有类型U(没有边界的类型变量),没有称为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类可以使用特定类型作为类型参数来实现该接口:

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

0
投票

只是为了让你明白

<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的确切语法。

© www.soinside.com 2019 - 2024. All rights reserved.