为什么我们使用“伴随对象"?作为 Kotlin 中 Java 静态字段的替代品? [英] Why do we use "companion object" as a kind of replacement for Java static fields in Kotlin?
问题描述
伴随对象"的预期含义是什么?到目前为止,我一直在使用它只是在需要时替换 Java 的 static
.
What is the intended meaning of "companion object"? So far I have been using it just to replace Java's static
when I need it.
我很困惑:
- 为什么叫同伴"?
- 这是否意味着要创建多个 静态 属性,我必须将它们组合在
companion object
块中? - 为了立即创建一个作用域为类的单例实例,我经常写
- Why is it called "companion"?
- Does it mean that to create multiple static properties, I have to group it together inside
companion object
block? - To instantly create a singleton instance that is scoped to a class, I often write
:
companion object {
val singleton by lazy { ... }
}
这似乎是一种单调的做法.什么是更好的方法?
which seems like an unidiomatic way of doing it. What's the better way?
推荐答案
-
伴随对象"的预期含义是什么?为什么叫同伴"?
What is the intended meaning of "companion object"? Why is it called "companion"?
首先,Kotlin 没有使用
static
成员的 Java 概念,因为 Kotlin 有自己的object
s 的概念,用于描述与单例状态相关的属性和函数,以及 Javastatic
类的一部分可以用单例来优雅地表达:它是一个可以通过类的名称调用的单例对象.因此命名:它是一个带有类的对象.First, Kotlin doesn't use the Java concept of
static
members because Kotlin has its own concept ofobject
s for describing properties and functions connected with singleton state, and Javastatic
part of a class can be elegantly expressed in terms of singleton: it's a singleton object that can be called by the class' name. Hence the naming: it's an object that comes with a class.它的名字曾经是
class对象
和默认对象
,然后重命名为companion object
更清晰,也与 Scala 配套对象.Its name used to be
class object
anddefault object
, but then it got renamed tocompanion object
which is more clear and is also consistent with Scala companion objects.除了命名之外,它比 Java
static
成员更强大:它可以扩展类和接口,您可以像其他对象一样引用和传递它.Apart from naming, it is more powerful than Java
static
members: it can extend classes and interfaces, and you can reference and pass it around just like other objects.这是否意味着要创建多个静态属性,我必须在
companion object
块内将它们组合在一起?Does it mean that to create multiple static properties, I have to group it together inside
companion object
block?是的,这是惯用的方式.或者您甚至可以根据它们的含义将它们分组为非伴随对象:
Yes, that's the idiomatic way. Or you can even group them in non-companion objects by their meaning:
class MyClass { object IO { fun makeSomethingWithIO() { /* ... */ } } object Factory { fun createSomething() { /* ... */ } } }
-
为了立即创建一个作用域为类的单例实例,我经常编写
/*...*/
这似乎是一种单一的方式.什么是更好的方法?To instantly create a singleton instance that is scoped to a class, I often write
/*...*/
which seems like an unidiomatic way of doing it. What's the better way?这取决于您在每种特定情况下的需求.您的代码非常适合存储绑定到在第一次调用时初始化的类的状态.
It depends on what you need in each particular case. Your code suits well for storing state bound to a class which is initialized upon the first call to it.
如果你不需要它与类连接,只需使用对象声明:
If you don't need it to be connected with a class, just use object declaration:
object Foo { val something by lazy { ... } }
您还可以删除
lazy { ... }
委托 使属性在第一类使用时初始化,就像 Java 静态初始化器You can also remove
lazy { ... }
delegation to make the property initialize on first class' usage, just like Java static initializers您可能还会找到初始化单例状态的有用方法.
这篇关于为什么我们使用“伴随对象"?作为 Kotlin 中 Java 静态字段的替代品?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!