Is there a difference between an anonymous object and singleton object

I have a lot of static information in objects. There is need that the objects are singleton, but the information is all hard-coded. Is there a reason to pick this syntax

val myObject = object : MyInterface {}

over this

object MyObject : MyInterface {}

?

I’ve almost never seen the first one.

You can use the first one in a function body if your object depends on some state of the function you’re in.

But at global scope there’s no reason to use the val = syntax afaik

1 Like

It can have different initialization time during JVM class loading.

In the first example, the object will be initialized when any access to synthetic class members for the defined file (FileKt.class for file.kt). In the second, initialization is only when the specific class is accessed.

Interesting. I thought there might also be a difference for anonymous types versus object types.

Or maybe like this:

val myObject = MyOpenClass()

versus


object MyObject : MyOpenClass {}

In this case, is there a (I guess minor) overhead for MyObject?

here you only create an instance of MyOpenClass.

This creates a new Type as well as an instance you can use so they are 2 different concepts. Unless you want to create a new type (eg to add additional fields, overrieds, etc) using MyOpenClass directly is probably the cleaner option.

Kinda. As you pointed out val myObject = object MyObject : MyInterface {} creates an anonymous type which means that you can’t refer to that type directly. You have to use the interface instead. Can’t think of many situations where it would make a difference though.

True, but I would argue that relying on JVM initialization specifics like this is a recipe for desaster. It’s something that can easily be broken by refactoring and cause really hard to find bugs in the long run. There is a reason that kotlin doesn’t define the exact initialization time. ok, sure the main reason is that it’s not really possible on the jvm but I don’t think there are any guarantees on the other platforms.

1 Like

The difference indeed is that for an object the type is visible (and can be used by clients). For an anonymous type, the type is invisible and cannot be used. Having a public object makes the object type accessible by definition (you can keep the members private thoug). The main point where this makes a difference is if you don’t want the type itself to be part of your API. In that case it is mostly equivalent to:

private object MyObject: MyInterface
val myObject: MyInterface = MyObject
1 Like