Java statics are not related to the concept of singletons. A Java static is actually closer to the concept of functions outside of classes in Kotlin. That is, a Java static method or field is a hard reference to method or field that has all of the namespace collision protections of classes and interfaces, and all of the implicit references within the class, that is simply not an instance of the class, but is otherwise a useful paradigm to be bundled with the class. One of the really nice features of Java is that you don’t need to add the class name reference to a static method or field that is within the same class, both from other statics as well as instance methods and initializers. One of Swift’s most glaring failures is the namespace problem - there are no packages, and there are places in the language that require explicit references to the context, resulting in bloated source code that still has namespace collision issues. Java’s solution to the namespace organization and collision issue of large systems was groundbreaking 25 years ago. Why did Kotlin decide to change it? (I assume that a possible answer to that question is this - ‘if it ain’t broke, don’t fix it’ is obviously an anti-pattern for programming language designers.)
I do not agree that somehow a “companion object” is consistent with the design of Kotlin. What design paradigm is it compatible with that statics are not? But then again I’m new here, so maybe I just don’t get it.
Again, I ask, are there any advantages of “companion object” vs statics that I don’t understand?
Is “companion object” a feature of functional programming languages? Is Scala where the construct originated? FWIW, I’ve never encountered an actual large application built with Scala … or Haskell for that matter. Functional programming is a fetish that seems cool but is detrimental to creation, understanding and maintenance of large systems, IMO.