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 修饰符来限定类型参数,现在可以在函数内部访问它了, 几乎就像是一个普通的类一样。由于函数是内联的,不需要反射,正常的操作符如 !is 和 as 现在都能用了。

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

1. inline fun <reified T> membersOf() = T::class.members

3. fun main(s: Array<String>) {
4. println(membersOf<StringBuilder>().joinToString("\n"))
5. }

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