8.2.14 具体化的类型参数

有时候我们需要访问一个参数类型:

  1. fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? {
  2. var p = parent
  3. while (p != null && !clazz.isInstance(p)) {
  4. p = p.parent
  5. }
  6. @Suppress("UNCHECKED_CAST")
  7. return p as T?
  8. }

在这里我们向上遍历一棵树并且检查每个节点是不是特定的类型。
这都没有问题,但是调用处不是很优雅:

  1. treeNode.findParentOfType(MyTreeNode::class.java)

我们真正想要的只是传一个类型给该函数,即像这样调用它:

  1. treeNode.findParentOfType<MyTreeNode>()

为能够这么做,内联函数支持具体化的类型参数,于是我们可以这样写:

  1. inline fun <reified T> TreeNode.findParentOfType(): T? {
  2. var p = parent
  3. while (p != null && p !is T) {
  4. p = p.parent
  5. }
  6. return p as T?
  7. }

我们使用 reified 修饰符来限定类型参数,现在可以在函数内部访问它了,
几乎就像是一个普通的类一样。由于函数是内联的,不需要反射,正常的操作符如 !isas 现在都能用了。

虽然在许多情况下可能不需要反射,但我们仍然可以对一个具体化的类型参数使用它:

  1. inline fun <reified T> membersOf() = T::class.members
  2. fun main(s: Array<String>) {
  3. println(membersOf<StringBuilder>().joinToString("\n"))
  4. }

普通的函数(未标记为内联函数的)没有具体化参数。