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.
3 Answers 3
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.
-
2That'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– user14462017年08月28日 19:13:58 +00:00Commented Aug 28, 2017 at 19:13
-
1And this is exactly why in Java I prefer to define methods on statically constructed stateless objects rather than define static methods.candied_orange– candied_orange2017年08月29日 06:49:52 +00:00Commented Aug 29, 2017 at 6:49
-
(Not having used Kotlin recently, or Java ...) I would think that you can test companion objects easier than static (methods) since they can be mocked without any trouble (e.g., without getting into bytecode rewriting, etc.)davidbak– davidbak2021年12月08日 01:11:04 +00:00Commented Dec 8, 2021 at 1:11
-
@davidbak I tend to think this is a superior concept to statics at least from a language usability perspective.JimmyJames– JimmyJames2021年12月08日 14:51:42 +00:00Commented Dec 8, 2021 at 14:51
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
.
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– Giorgio2017年08月29日 05:00:43 +00:00Commented Aug 29, 2017 at 5:00
-
1I think it's at least arguable that Java does (somewhat) implement that pattern. For instance, if you have
MyStaticClass
with somestatic
members, you can referenceMyStaticClass.class
to get aClass
instance for that class. You can then use reflection to access/invoke yourstatic
members. It's still true that thestatic
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– aroth2017年08月29日 10:45:58 +00:00Commented Aug 29, 2017 at 10:45
Explore related questions
See similar questions with these tags.
static
keyword in Java, it immediately propagates to all corners of the program because they have not yet been taught object-oriented programming.