微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么不能访问 reified 类型参数的伴生对象?

如何解决为什么不能访问 reified 类型参数的伴生对象?

在下面,由于 T 是具体化的,我想通过访问它的伴随对象来使用它 "almost as if it were a normal class"

class Cls {
  companion object {
    fun method() { }
  }    
}

inline fun <reified T> func() {
  T.method()  // error
}

fun main() {
  func<Cls>()
}

但是失败了

Type parameter 'T' cannot have or inherit a companion object,so it cannot be on the left hand side of dot

因此似乎丢失了大量信息。使用和不使用 reified 时我都会遇到相同的错误。我希望 reified 类型参数比 Java 的实现更全面。我在 C++ 模板方面拥有丰富的经验。

我找到了一些解决方法(使用反射都非常令人失望),但我真的在问为什么这行不通。

解决方法

我不确定这是否回答了所有问题,但评论太大了。

首先,正如评论中所述,代码的编写方式,T 不一定是 Cls,因此您需要进行一些更改:

open class Cls {
  companion object {
    fun method() { }
  }    
}

inline fun <reified T : Cls> func() {
  
}

打开课程,让 Kotlin 知道 T 是一个 Cls

然而,即使它是内联的,这仍然不会让您调用伴随方法,因为 T 没有伴随方法。即使没有泛型:

open class Cls {
  companion object {
    fun method() { }
  }    
}

class Foo : Cls

fun main() = Foo.method() // doesn't work

不起作用,因为同伴不是继承的。为什么?这是 Kotlin 设计师有意识的决定。如您所知,Kotlin 旨在纠正 Java 存在的许多问题,这就是其中之一。

Java 中的静态方法是在编译时绑定的,而覆盖是基于运行时的动态绑定。当您将两者混合使用时,这会变得非常混乱,而 Kotlin 试图避免这种情况。举个例子:

class Cls {
    public static void method() {
        System.out.println("Cls' method");
    }
}

class Foo extends Cls {
    public static void method() {
        System.out.println("Foo's method");
    }
}

public class Main {
    public static void main(String[] args) {
        Cls parent = new Foo();
        parent.method();
    }
}

如果 method 真的被覆盖,它会打印出 Foo's method,但确实会打印出 Cls' method。原因是没有覆盖,但有阴影发生。另一方面,如果方法不是静态的,那么您会得到 Foo's method,因为它确实被覆盖了。这显然引起了开发人员的混淆,Kotlin 完全不允许这样做。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?