为什么公共内联函数可以调用私有构造函数

时间:2017-09-12 12:18:49

标签: kotlin

我的类有一个私有构造函数,并在伴随对象上实现了对某种"泛型构造函数的调用"

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

不应该意味着每个in​​vokation test()都会扩展为Test(Any::class.java.name),即使该构造函数是私有的吗?

所以我的问题是:

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

2 个答案:

答案 0 :(得分:1)

  
      
  • 为什么内部内联乐趣可以调用私有构造函数? (公共乐趣不能)
  •   

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

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

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

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

这是由于第一点中预期行为的组成和第二点中的错误。最终,它也是一个错误。

答案 1 :(得分:0)

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

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