【问题标题】:Nested Groovy generics: unexpected token on inner generic type嵌套 Groovy 泛型:内部泛型类型上的意外标记
【发布时间】:2015-11-04 06:29:15
【问题描述】:

请注意:尽管这个问题专门针对 Netflix' Hystrix 库,但本质上这绝对是一个纯 Groovy/JVM 泛型问题。任何厌战 Java/Groovy 的老手都应该能够回答这个问题,无论他们对 Hystrix 的知识/经验如何。


我想构建一个抽象基 HystrixCommand 以返回 Guava Optionals 作为它们的通用 RESULT 类型:

import com.google.common.base.Optional
import com.netflix.hystrix.HystrixCommand

abstract class BaseHystrixCommand<Optional<RESULT>> extends HystrixCommand {
    // My code here...
}

但是此代码会产生以下编译器错误:

Groovy:unexpected token:

第 23 行第 42 列是 RESULT 的内开口尖括号:

...BaseHystrixCommand<Optional<RESULT...
                              ^ right here

在这里使用 Java 8、Groovy 2.4.3、Hystrix 1.4.18 和 Guava 18.0。任何想法是什么导致了这个编译器错误?

【问题讨论】:

    标签: java generics groovy guava hystrix


    【解决方案1】:

    你不能在你的类型参数中使用中间类型,你只需直接声明类型参数,然后使用参数化的Optional作为方法参数或返回类型:

    abstract class BaseHystrixCommand<T> extends HystrixCommand {
        Optional<T> someMethod();
    }
    

    您还可以在第一个的基础上创建第二个绑定类型参数(虽然这里的示例很愚蠢,但您不会扩展 Optional),但您需要在实例化时指定其具体类型:

    abstract class BaseHystrixCommand<T, U extends Optional<T>> extends HystrixCommand {
        U someMethod();
    }
    

    更新

    HystrixCommand其实是一个参数化的类,你想让它的参数化方法(比如run())返回一个Optional。只需在子类中正确参数化HystrixCommand

    abstract class BaseHystrixCommand<T> extends HystrixCommand<Optional<T>> {
        // ...
    }
    

    当然,所有返回参数化类型的方法现在都将返回一个Optional,它与原始声明保持一致。

    旁注:您确实希望对参数化类型使用单个字母,以避免与常量混淆并遵循样式约定。

    【讨论】:

    • 感谢@Frank Pavageau (+1) - 问题是通过扩展HystrixCommand 我必须重写几个方法,例如HystrixCommand#run。我希望我的run() 覆盖返回一个Optional&lt;RESULT&gt;不是只是一个RESULT。这里有什么想法吗?听起来我唯一的做法是使用虚拟包装器对Optional 进行子类化,然后使用BaseHystrixCommand&lt;OPTIONAL extends Optional&lt;RESULT&gt;&gt;
    • 比如class OptionalWrapper&lt;RESULT&gt; extends Optional&lt;RESULT&gt; { }?
    • 我已编辑我的答案以解决您的其他问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    相关资源
    最近更新 更多