【问题标题】:Getting Class of list with generic eg: List<Number>::class使用泛型获取列表类,例如:List<Number>::class
【发布时间】:2016-05-03 23:33:00
【问题描述】:

我有一个通用类型的类Builder&lt;T&gt;,它接受一个构造函数参数Class&lt;T&gt;,所以我可以保留这个类型。这是我在 java 代码中经常使用的一个类,所以我不想更改签名。 当我尝试像这样使用构造函数时:

Builder&lt;List&lt;Number&gt;&gt;(List&lt;Number&gt;::class)

我收到一个错误:“类文字的左侧只允许使用类”

有什么办法解决这个问题吗? 我无法更改 Builder 的构造函数,太多的 java 类依赖它。

我了解整个类型擦除问题,我真的只是想让编译器开心。

【问题讨论】:

    标签: generics kotlin


    【解决方案1】:

    由于generic type erasure List 类对其所有通用实例化都有一个实现。只能获取List&lt;*&gt;类型对应的类,因此只能创建Builder&lt;List&lt;*&gt;&gt;

    该构建器实例适合构建某物的列表。再次由于类型擦除,您可以在未经检查的强制转换的帮助下自行决定:

    Builder(List::class.java) as Builder<List<Number>>
    Builder(List::class.java as Class<List<Number>>)
    

    另一种方法是创建内联具体化辅助函数:

    inline fun <reified T : Any> Builder() = Builder(T::class.java)
    

    并按照以下方式使用它:

    Builder<List<Number>>()
    

    【讨论】:

    • 物化才是王道
    • 这不会保留实际的类型参数:T::class.java 将代表 List&lt;*&gt;,而不是 List&lt;Number&gt;,但有一个解决方案可以针对具体化的泛型——超类令牌。跨度>
    • @hotkey 我假设 Builder 类不需要保留实际类型参数,因为它需要一个构造函数参数 Class&lt;T&gt; 而不是问题中所述的 Type。跨度>
    • @Ilya 什么是 Builder 类?可以提供包名吗?
    • @alexeypolusov 这是问题中的课程。
    【解决方案2】:

    解决方案是将reified genericssuper class tokens 结合使用。

    说明方法请参考this question。 Kotlin 中的构造函数不支持具体泛型,但您可以使用那里描述的TypeReference 编写一个builder 工厂函数,该函数将在运行时保留实际的泛型参数:

    inline <reified T: Any> fun builder(): Builder<T> {
        val type = object : TypeReference<T>() {}.type
        return Builder(type)
    }
    

    然后在Builder里面你可以检查type是不是ParameterizedType,如果是,type.actualTypeArguments会包含实际的泛型参数。

    例如,builder&lt;List&lt;Number&gt;&gt;() 将在运行时保留有关 Number 的信息。

    这种方法的限制是您不能使用非具体化的泛型作为具体化类型参数,因为类型必须在编译时已知。

    【讨论】:

      【解决方案3】:

      如果您已经在项目中使用 gson 库(例如 json 解析)。它为此提供了一个类。 com.google.gson.reflect.TypeToken()。所以你可以使用类似的东西,

       Builder<List<Number>>(object : TypeToken<List<Number>>() {}.type::class)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-20
        • 2015-12-12
        相关资源
        最近更新 更多