As a C# developer migrating to Java and Kotling I often looking for a ways to implement known coding concepts but in new language.
One of these concepts is disposable objects with using keyword. If your objects holds resources and you want them to be automatically released when no longer needed, you define as code scope with using keyword. Consider following example:
public class MyResource : IDisposable
{
public void DoWork()
{
Console.WriteLine("Doing useful work");
}
public void Dispose()
{
Console.WriteLine("Releasing resources");
}
}
using (var myResource = new MyResource())
{
myResource.DoWork();
}
Console.WriteLine("Code outside of using");
Here we defined an instance of MyResource class inside using keyword. When execution of the code exits using block the Dispose() method will be automatically invoked.
If you run it, the output will be following:
Doing useful work
Releasing resources
Code outside of using
Process finished with exit code 0.
As you can see the line Releasing resources goes right at the moment the execution exits using block.
In real projects there are several ways to implement Dispose method. If your class uses unmanaged resources or has subclasses, the implementation pattern will be different. You can read more details on page: https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose
What is in Java ?
There is simillar concept in Java. The AutoClosable interface in Java plays similar role as Disposable in C#. The close() method should release resources after they are not needed anymore. The method will be automatically called by JVM when exiting a try-with-resources block.
Consider following example:
public class MyResource implements AutoCloseable {
public void doWork() {
System.out.println("Doing useful work");
}
@Override
public void close() throws Exception {
System.out.println("Releasing resources");
}
}
public class Main {
public static void main(String[] args) throws Exception {
try(var myResource = new MyResource()) {
myResource.doWork();
}
System.out.println("Code outside of try-with-resources");
}
}
Does the code looks falimiar? :) If you compile and run this program, the output will be very simillar:
Doing useful work
Releasing resources
Code outside of try-with-resources
Process finished with exit code 0
The Kotlin approach
The creators of Kotlin language decided to follow different approach. There is no language construct like using or try-with-resources. Instead the team provided a standard library with extension method called use().
The developer can invoke use() method on any object which implements AutoClosable. The use() extension function simply takes input lambda expression, executes it and releases resources by calling close() method.
Let's take a look at example:
class MyResource : AutoCloseable {
fun doWork() {
println("Doing useful work")
}
override fun close() {
println("Releasing resources")
}
}
fun main() {
MyResource().use {
it.doWork()
}
println("Code outside of use")
}
In the example above we invoked use() extension method without defining a new variable, but using implicit variable it instead.
The output is similar:
Doing useful work
Releasing resources
Code outside of use
Process finished with exit code 0
So, implementing objects with auto-disposable resources in Kotlin and Java is quite simple. They both rely on AutoClosable interface. The difference is the Kotlin uses extension method to create a resource related scope, while Java prefers dedicated language construct.
Comments