This is a question about language design rather than trying to solve a specific problem.
I noted two oddities about object instances inside companion objects:
- object instances can't be referenced without the
.Companion - object instances cannot be annotated @JvmStatic
As shown below, neither constraint applies to functions defined within companion objects. The distinction for apparently for what appear to be sibling declarations is a bit of mental overhead I'd rather not have to deal with.
Is there an example that demonstrates why these constraints were necessary? Presumably for Java interop, but I have yet to think of the case.
class MyClass {
companion object {
@JvmStatic
fun myFunc() {}
//@JvmStatic // Error: This annotation is not applicable to target 'standalone object'
object MyObject {}
}
}
fun testingReferencing() {
MyClass.myFunc()
MyClass.Companion.myFunc() // Awkward and redundant, but works.
//val obj1 = MyClass.MyObject // Error: Unresolved reference: MyObject
val obj2 = MyClass.Companion.MyObject
}
This "restriction" is certainly not "necessary", but enabling you to access object declarations this way would probably lead to more complexity in the compiler, to not only implement this, but also handle the edge cases, and various other features that might interact with the change.
And anyway, this is how type names work all along. The fact that you can access properties and methods without
Companionis the exception.MyClass.MyObjectrefers to an object/type calledMyObject, nested inMyClass. AndMyClass.Companion.MyObjectrefers to an object/type calledMyObjectnested in a type calledCompanion, which is itself nested in a type calledMyClass.This is just the way nested type names (whether they are objects, classes, or interfaces) are qualified.
JvmStaticis just unnecessary on type declarations. If you look at the annotation's declaration, it is only available on functions and properties.An
object(orclass, orenum class) declaration nested in another type already translates to astaticnested class in Java. e.g.translates to something like
Whether or not it is in a companion object doesn't matter.
companion object, just likeclass, translates to a Java class, where the class for theobjectis nested.If you want a non-static JVM class, that is an
inner classin Kotlin.