Objects support init() but missing finalize type function


#1

I love the lazy initialization of Kotlin singleton objects but I am not seeing any way to implement some kind of finalizer which is executed when the application shuts down so I can do some cleanup. Is this a language feature that is missing?


#2

You can use java’s finalize method: https://kotlinlang.org/docs/reference/java-interop.html#finalize

class Test {
    fun finalize(){ // dont use override and can't be private
        // do something
    }
}

This however is not guaranteed to be called at all. This will only get called when the garbage collector removes the object from memory. This might not happen if your program terminates and there is no control when this will execute, so I would advice against using this.


In general this is a limitation on how the JVM works. Due to the GC there is no way of knowing when an object actually gets finalized so I would not put any must run code here.

If you have any resources which have to be finalized and cause problems if you don’t you have to do this manually.


#3

That may work for a class. I am specifically interested in a singleton object:

object A {
    init {
        println("initialized A")
    }

    wishThereWasAFinalize
    {

    }
}

#4

As I said, this might not even work for a class and is a limitation of the JVM. As far as I know the only option is to use a manual system for that kind of stuff. You could for example have your singletons implement a interface and also add them to a list which you can then iterate through at the end of your program.

interface Finalized {
    fun finalize()
}
val objectsToFinalize = emptyMutableList<Finalized>()

object A: Finalized {
    init { objectToFinalize.add(this) }
}

fun main(args: Array<String>){
    // execute program
    
    objectsToFinalize.forEach { it.finalize() }
}

Otherwise, I think you should be able to implement finalize for objects the same way you do for classes. The only drawback is that the chance of the gc removing them at the end is near 0.


#5

Interesting. I am looking at replacing a testing framework written Java/Spring and using Kotlin which looks to be more lightweight for what I need. It would be ideal if I could replace my Spring services with Kotlin objects and replace my @PostConstruct and @PreDestroy code with init{} and finalize{}.

Your proposed solution looks like it would meet my needs but obviously not quite as nifty as it would be if Kotlin and the JVM supporting a finalize function for singleton objects.

Thanks. I will head down this path.


#6

I mean if you need this often you could probably do most of the initialization using Kapt. Using the ProcessingEnvironment and RoundEnvironment maybe in combination of the kotlin metadata framework you should be able to iterate over all classes implementing the interface and create the list at compile time. That way you could ensure you don’t forget to add an object to the objectsToFinalize.


#7

If you want to free up some kind of resources when the object is destroyed, it should implement AutoCloseable interface. It has a method close which is invoked either manually, or when object leaves scope. It is also a good practice to use it in combination with try with resources constructs (use extension in case of Kotlin).

I am not sure about singletons though. I think, it is considered bad architecture to allocate and free resources permanently in the singleton.


#8

I think that classes you propose have completely different lifecycles. Spring invokes the methods for construction and destruction of services whenever it needs. init method is invoked on singleton creation in other words on class load, which could not be controlled in any way.

Generally, you should not ever put anything but property configuration in init block. So if you have some kind of meaningful actions in initialization, you should still use some kind of start/stop methods and call the explicitly in your application lifecycle.