Gosu重写Java泛型方法遇reified要求的问题求助
解决Gosu实现gRPC ServerInterceptor时泛型reified报错问题
当使用Gosu基于Java 11开发gRPC服务端拦截器,实现io.grpc.ServerInterceptor接口时,在interceptCall方法的catch块中返回空的ServerCall.Listener<ReqT>匿名实例,会触发如下报错:
The method 'interceptCall<ReqT, RespT>' must be declared with the 'reified' modifier to access the type variable 'ReqT' at runtime
由于原接口的interceptCall方法未标记reified,重写时无法添加该修饰符,导致无法直接创建带方法级泛型参数的匿名Listener实例。以下是两种可行的解决方案:
方案1:强制类型转换绕过泛型检查
空实现的Listener无需处理任何请求数据,因此可以创建无泛型约束的匿名Listener实例,再强制转换为目标泛型类型:
class AuthServerInterceptor implements ServerInterceptor { private static final var AUTHORIZATION_METADATA_KEY = Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER) override function interceptCall<ReqT, RespT>( call : ServerCall<ReqT, RespT>, headers : Metadata, next : ServerCallHandler<ReqT, RespT> ) : ServerCall.Listener<ReqT> { try { var token = headers.get(AUTHORIZATION_METADATA_KEY) // 此处添加JWT令牌校验逻辑 return next.startCall(call, headers); } catch (e : Exception) { call.close(Status.UNAUTHENTICATED.withDescription(e.message), headers); // 强制转换绕过泛型检查 return (ServerCall.Listener<ReqT>) new ServerCall.Listener<>() {} } } }
方案2:复用静态空Listener实例(更高效)
提前创建一个静态的空Listener实例,每次需要时直接转换复用,避免重复创建对象:
class AuthServerInterceptor implements ServerInterceptor { private static final var AUTHORIZATION_METADATA_KEY = Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER) // 静态空Listener实例,全局复用 private static final var EMPTY_LISTENER = new ServerCall.Listener<>() {} override function interceptCall<ReqT, RespT>( call : ServerCall<ReqT, RespT>, headers : Metadata, next : ServerCallHandler<ReqT, RespT> ) : ServerCall.Listener<ReqT> { try { var token = headers.get(AUTHORIZATION_METADATA_KEY) // 此处添加JWT令牌校验逻辑 return next.startCall(call, headers); } catch (e : Exception) { call.close(Status.UNAUTHENTICATED.withDescription(e.message), headers); return (ServerCall.Listener<ReqT>) EMPTY_LISTENER } } }
原理说明
Gosu在创建带有方法级泛型参数的匿名内部类时,要求方法标记reified以在运行时获取类型信息。但由于我们的空Listener所有方法都是默认空实现,不涉及任何ReqT类型的实际操作,因此强制类型转换是安全的,不会引发类型相关的运行时异常。
内容的提问来源于stack exchange,提问作者MRoose
相关产品推荐
相关产品推荐

