Why do we use “companion object” as a kind of replacement for Java static fields in Kotlin?

前端 未结 4 1371
鱼传尺愫
鱼传尺愫 2020-11-29 19:23

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.

I am confused with:

相关标签:
4条回答
  • 2020-11-29 19:40
    • What is the intended meaning of "companion object"? Why is it called "companion"?

      First, Kotlin doesn't use the Java concept of static members because Kotlin has its own concept of objects for describing properties and functions connected with singleton state, and Java static 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.

      Its name used to be class object and default object, but then it got renamed to companion object which is more clear and is also consistent with Scala companion objects.

      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.

    • 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 { ... }
      }
      

      You can also remove lazy { ... } delegation to make the property initialize on first class' usage, just like Java static initializers

      You might also find useful ways of initializing singleton state.

    0 讨论(0)
  • 2020-11-29 19:45

    Why is it called "companion"?

    An object declaration inside a class can be marked with the companion keyword:

    class MyClass {
        companion object Factory {
            fun create(): MyClass = MyClass()
        }
    }
    

    Members of the companion object can be called by using simply the class name as the qualifier:

    val instance = MyClass.create()
    

    If you only use 'object' without 'companion', you have to do like this:

    val instance = MyClass.Factory.create()
    

    In my understanding, 'companion' means this object is companion with the outter class.

    0 讨论(0)
  • Why is it called "companion"?

    This object is a companion of the instances. IIRC there was lengthy discussion here: upcoming-change-class-objects-rethought

    Does it mean that to create multiple static properties, I have to group it together inside companion object block?

    Yes. Every "static" property/method needs to be placed inside this companion.

    To instantly create a singleton instance that is scoped to a class, I often write

    You do not create the singleton instance instantly. It is created when accessing singleton for the first time.

    which seems like an unidiomatic way of doing it. What's the better way?

    Rather go with object Singleton { } to define a singleton-class. See: Object Declarations You do not have to create an instance of Singleton, just use it like that Singleton.doWork()

    Just keep in mind that Kotlin offers other stuff to organize your code. There are now alternatives to simple static functions e.g. you could use Top-Level-Functions instead.

    0 讨论(0)
  • 2020-11-29 20:00

    We can say that companion is same as "Static Block" like Java, But in case of Kotlin there is no Static Block concept, than companion comes into the frame.

    How to define a companion block:

    class Example {
          companion object {
            fun display(){
            //place your code
         }
      }
    }
    

    Calling method of companion block, direct with class name

    Example.Companion.display
    
    0 讨论(0)
提交回复
热议问题