【问题标题】:How to call constructor of generic type in class constructor如何在类构造函数中调用泛型类型的构造函数
【发布时间】:2016-04-05 14:10:09
【问题描述】:

我想创建具有以下属性的类 Matrix2D

  1. 类应该是通用的
  2. 应该能够接受尽可能多的类型(最好是全部)
  3. “默认”构造函数应使用默认类型值初始化所有单元格
  4. 正确处理大小写,当类型没有默认构造函数时(可能默认参数解决了这个问题)

我该怎么做? 这是我的草图:

class Matrix2D<T> : Cloneable, Iterable<T> {
    private val array: Array<Array<T>>
    // Call default T() constructor if it exists
    // Have ability to pass another default value of type
    constructor(rows: Int, columns: Int, default: T = T()) {
        when {
            rows < 1 -> throw MatrixDimensionException("Number of rows should >= 1")
            columns < 1 -> throw MatrixDimensionException("Number of columns should be >= 1")
        }
        array = Array(rows, { Array(columns, { default }) })
    }
}

【问题讨论】:

    标签: generics kotlin


    【解决方案1】:

    没有办法在编译时检查一个类是否有默认构造函数。我会通过传递一个创建给定类型实例的工厂来解决这个问题:

    class Matrix2D<T : Any> : Cloneable, Iterable<T> {
      private val array: Array<Array<Any>>
    
      constructor(rows: Int, columns: Int, default: T) :
          this(rows, columns, { default })
    
      constructor(rows: Int, columns: Int, factory: () -> T) {
        when {
          rows < 1 -> throw MatrixDimensionException("Number of rows should >= 1")
          columns < 1 -> throw MatrixDimensionException("Number of columns should be >= 1")
        }
        array = Array(rows) { Array<Any>(columns) { factory() } }
      }
    }
    

    请注意,在这种情况下,您不能使用 T 类型的数组,因为有关其实际类型的信息在运行时会被删除。只需使用 Any 的数组并在必要时将实例转换为 T

    【讨论】:

    • 这看起来如果我们使用Any 我们不需要第二个构造函数:constructor(rows: Int, columns: Int, test: T) { when { rows throw MatrixDimensionException( "行数应该 >= 1") 列 throw MatrixDimensionException("列数应该 >= 1") } array = Array(rows) { Array(columns) { test as Any } } } Is'是吗?
    • 这只是一个方便的构造函数,你可以删除它。它实际上与Any 无关。
    【解决方案2】:

    不能在默认参数中调用默认构造函数。

    Reified generics 仅在内联函数中可用。

    【讨论】:

      猜你喜欢
      • 2017-03-12
      • 1970-01-01
      • 2021-08-17
      • 2010-10-16
      • 2019-09-19
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多