【问题标题】:Why can public inline functions call private constructors为什么公共内联函数可以调用私有构造函数
【发布时间】:2018-02-20 21:43:48
【问题描述】:

我的类有一个私有构造函数,并为某种“通用构造函数”在伴随对象上实现了调用

class Test private constructor(className: String) {
    companion object {
        // If I remove the internal it fails 
        internal inline operator fun <reified T> invoke(): Test {
            return Test(T::class.java.name) // why can I even call it? The constructor is private
        }
    }
}

我什至可以拥有一个调用通用构造函数的公共内联函数

public inline fun test() = Test<Any>() // Why can I call it, it is internal

这不应该意味着每次调用 test() 都会扩展为 Test(Any::class.java.name),即使该构造函数是私有的?

所以我的问题是:

  • 为什么internal inline fun 可以调用私有构造函数? (公共乐趣不能)
  • 为什么public inline fun 可以调用内部函数?
  • 为什么我最终可以在 public inline fun 中公开私有构造函数?

【问题讨论】:

    标签: kotlin


    【解决方案1】:
    • 为什么内部内联 fun 可以调用私有构造函数? (公共乐趣不能)

    internalinline函数可以访问非公共API,因为它只能在同一个模块中调用,因此不会受到可能引入的二进制不兼容的影响当 API 更改且调用模块未重新编译时(请参阅docs)。只有公共 API inline 函数才禁止此类调用。

    • 为什么公共内联函数可以调用内部函数?

    这是一个错误。通常,公共inline 函数无法访问非公共 API。 invoke() 操作员调用似乎没有检查此规则。我已提交问题:KT-20223。

    • 为什么我最终可以在公共内联乐趣中公开私有构造函数?

    这是由于第一点中的预期行为和第二点中的错误的组合。归根结底,这也是一个错误。

    【讨论】:

      【解决方案2】:

      伴生对象在类中。所以类中的代码提供了一个接口来调用私有方法,但是记住这段代码是类中的代码。

      就像公共类方法可以访问私有变量并将它们的值返回给外部一样,这些方法可以这样做,因为它们是类的一部分。同样的原则也适用于这种情况,所以我建议这种从类中访问私有成员的能力是可以预期的,而不太预期的行为是类的常规内联函数的行为。我相信常规内联函数在这方面的行为是一种实现限制,而伴随对象根本不需要。

      【讨论】:

      • 那不适用于内联函数
      • 非常正确,但我认为这是对 JVM 的限制,而不是设计选择,因为普通函数确实具有这样的访问权限。我的观点是,这种访问能力更符合预期,而不是问题。
      猜你喜欢
      • 2011-02-08
      • 1970-01-01
      • 2017-04-30
      • 2011-10-23
      • 1970-01-01
      • 2011-12-06
      • 2016-07-31
      • 2011-04-16
      • 2019-10-16
      相关资源
      最近更新 更多