29

Kotlin is known primarily as a drop-in replacement for Java, but it gets rid of a well-known Java construct: the static keyword. Instead, that class-level functionality is offered mainly by companion objects.

What is wrong with static methods and fields that companion objects provide a better alternative to? I'm confused about the rationale, and couldn't find any explanation in the documentation.

  • 4
    Just spectating as someone who programs in scala: companion objects separate the code for static and non static methods, they can extend other classes or interfaces in a static context, and you can reference the companion object in a variable. not sure how that maps to kotlin though – Phoenix Aug 28 '17 at 18:35
  • Do static methods and whatnot have any significant advantage over companion objects? – Tanner Swett Aug 28 '17 at 19:00
  • This isn't the reason, more an observation, but I have seen that as soon as (absolute) beginner programmers discover the static keyword in Java, it immediately propagates to all corners of the program because they have not yet been taught object-oriented programming. – Score_Under Aug 29 '17 at 9:58
30

Scala also replaces class level declarations with a 'Singleton' object. The main advantage of this is that everything is an object. In Java, static members are treated very differently than object members. This means that you can't do things like implementing an interface or putting your class 'instance' into a map or pass it as a parameter to a method that takes Object. Companion objects allow for these things. That's the advantage.

  • 1
    That's a good point. And I've always thought it was weird that there are singletons and statics that have very similar behaviors, but with nothing but companion objects, it does away with that conceptual oddity. – user1446 Aug 28 '17 at 19:13
  • 1
    And this is exactly why in Java I prefer to define methods on statically constructed stateless objects rather than define static methods. – candied_orange Aug 29 '17 at 6:49
13

Citing from the Kotlin reference docs:

Note that, even though the members of companion objects look like static members in other languages, at runtime those are still instance members of real objects, and can, for example, implement interfaces.

Sounds very much to me like the Kotlin designers see this as an advantage over Java's static members.

Moreover, the part about Java interoperability and static members explains how companion objects can be used to create members which behave effectively like static members when annotated with @JvmStatic.

6

Kotlin is an object-oriented language. In an object-oriented language, something not being an object is an extremely crippling restriction. Classes aren't objects, but objects are objects (duh!), so the question should rather be: why would a language not use companion objects?

Another aspect is simplicity: why have two things, objects with instance members and classes with static members when you can just have objects with instance members?

An alternative that is used in many Smalltalk-derived languages, is to make classes themselves objects. E.g. in Smalltalk classes are instances of a parallel hierarchy of metaclasses. In Ruby, classes are instances of the Class class (and yes, that means that Class is an instance of itself). In that case, "class methods" are actually just normal instance methods of the class's metaclass. I don't know why this design wasn't chosen in Java (given its close to relation to Smalltalk), but it may have something to do with simplifying the type system (note that most languages with classes-as-objects tend to be dynamic languages).

  • 1
    "Another aspect is simplicity: why have two things, objects with instance members and classes with static members when you can just have objects with instance members?": Good point, even though not all languages / language designers aim at minimalism. Some see it as an advantage to have ad-hoc constructs for special cases or idioms. – Giorgio Aug 29 '17 at 5:00
  • 1
    I think it's at least arguable that Java does (somewhat) implement that pattern. For instance, if you have MyStaticClass with some static members, you can reference MyStaticClass.class to get a Class instance for that class. You can then use reflection to access/invoke your static members. It's still true that the static members aren't actually attached to any object instance (at least conceptually; not sure what Java actually does under the covers). But it does mean that at least some of the limits raised in the accepted answer don't strictly apply. – aroth Aug 29 '17 at 10:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.