When a companion object is declared within a Kotlin class, the compiler will generate an inner class named Companion during compilation. Here, we've defined an empty companion object on a Widget class:
class Widget {
companion object { }
}
From the preceding code snippet, the following Java code is generated by the compiler:
public final class Widget {
public static final Widget.Companion Companion = new Widget.Companion((DefaultConstructorMarker)null);
...
public static final class Companion {
private Companion() {
}
...
}
}
As you can see here, any time an instance of the enclosing Widget class is instantiated, an associated instance of the inner Companion class will also be instantiated. From Java, properties and methods of the Companion class can then be referenced via that instance:
// Main.java
public class Main {
public static void main(String[] args) {
Widget.Companion.goo();
}
}
Defining companion objects in this way provides a Java syntax that looks very similar to static methods. However, these companion objects are, in fact, real objects that must be instantiated to be used. We will discuss how to modify the definition and usage of companion objects later in this chapter.