为什么我们使用“伴侣对象”作为Kotlin中Java静态字段的一种替代?
“伴侣对象”的意图是什么? 到目前为止,我一直在使用它来替代Java的static
当我需要它。
我很困惑:
- 为什么叫“同伴”?
- 这是否意味着要创建多个静态属性,我必须在
companion object
块内组合在一起? - 要立即创建一个范围为一个类的单例实例,我经常写
:
companion object { val singleton by lazy { ... } }
这似乎是一个单一的做法。 什么是更好的方法?
-
“伴侣对象”的意图是什么? 为什么叫“同伴”?
首先,Kotlin没有使用
static
成员的Java概念,因为Kotlin有自己的用于描述与单例状态相关的属性和函数的object
的概念 ,并且类的Javastatic
部分可以用单例来表达优雅地表达:它是一个单独的object
,可以通过类的名字来调用。 因此命名:这是一个类与一个对象。它的名称曾经是
class object
和default object
,但后来被重命名为companion object
,这个companion object
更加清晰,也与Scala伴侣对象一致。除了命名之外,它比Java
static
成员更强大:它可以扩展类和接口,并且可以像任何其他对象一样传递它。 -
这是否意味着要创建多个静态属性,我必须在
companion object
块内组合在一起?是的,这是惯用的方式。 或者,你甚至可以将它们分组在非伴侣对象中:
class MyClass { object IO { fun makeSomethingWithIO() { /* ... */ } } object Factory { fun createSomething() { /* ... */ } } }
-
要立即创建一个范围为一个类的单例实例,我经常写
/*...*/
,这看起来像是一种单一的方式。 什么是更好的方法?这取决于你在每个特定情况下需要什么。 你的代码适合存储绑定到一个类的初始化时的状态。
如果你不需要它与一个类连接,只需使用对象声明:
object Foo { val something by lazy { ... } }
您也可以像使用Java静态初始化器一样,移除
lazy { ... }
委托来使属性初始化第一类的用法你也可以找到初始化单身状态的有用方法。
为什么叫“同伴”?
这个对象是实例的伴侣。 IIRC在这里进行了长时间的讨论: 即将到来的改变阶级对象 – 重新思考
这是否意味着要创建多个静态属性,我必须在同伴对象块内组合在一起?
是。 每个“静态”属性/方法都需要放在这个同伴内。
要立即创建一个范围为一个类的单例实例,我经常写
您不要立即创建单例实例。 它是在第一次访问singleton
时创建的。
这似乎是一个单一的做法。 什么是更好的方法?
而是用object Singleton { }
来定义一个单例类。 请参阅: 对象声明您不必创建一个Singleton
实例,就像使用Singleton.doWork()
请记住,Kotlin提供了其他的东西来组织你的代码。 现在有一些简单的静态函数可供选择,例如可以使用顶层函数。