Skip to content

Instantly share code, notes, and snippets.

@behrangsa
Last active January 21, 2018 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save behrangsa/c2377262c2e3a7e5a1a39a4110712f52 to your computer and use it in GitHub Desktop.
Save behrangsa/c2377262c2e3a7e5a1a39a4110712f52 to your computer and use it in GitHub Desktop.
Java vs Kotlin

Here are two examples:

Example 1

In version 3.1.4 of the RabbitMQ client for Java, Connection does not implement Closeable so you can't use try-with-resources when creating a new connection.

You can't do this either:

ConnectionFactory connectionFactory = new ConnectionFactory();

final Connection connection;
try {
    connection = connectionFactory.newConnection();
} finally {
    connection.close();
}

because your program won't compile as "Variable 'connection' might not have been initialized".

You obviously can't do this either:

ConnectionFactory connectionFactory = new ConnectionFactory();

try {
    final Connection connection = connectionFactory.newConnection();
} finally {
    connection.close();
}

because connection is only defined within the scope of the try block.

If you want to make this work, you should do something like this:

ConnectionFactory connectionFactory = new ConnectionFactory();

Connection connection = null;
try {
    connection = connectionFactory.newConnection();
} finally {
    if (connection != null) {
        connection.close();
    }
}

This has 2 drawbacks:

  1. You can no longer declare connection final
  2. In your finally clause you have to check connection is not null before calling close() on it.

Ideally, the language should have allowed you to:

  1. Declare connection as final
  2. Do not force you to check it is not null in the finally clause.

From my limited experience with Kotlin, you can't do this in Kotlin either.

Example 2

Kotlin still has nulls.

@ilya-g
Copy link

ilya-g commented Jan 20, 2018

In the example 1 there's no sense in opening connection in try block. If newConnection fails the connection variable stays null, so there's nothing to close in finally block. Therefore you can move newConnection out of try and join connection declaration and assignment, making it back final (val in Kotlin).

@behrangsa
Copy link
Author

behrangsa commented Jan 21, 2018

Could you please show me a sample code?

I don't need access to the connection outside the try block. For example, all I need to do is something like this:

ConnectionFactory connectionFactory = new ConnectionFactory();

try {
    final Connection connection = connectionFactory.newConnection();
    doSomething(connection);
} finally {
    connection.close();
}

But connection.close() fails here. If finally had the same scope as the try block, I could have done something like this (in pseudo-code):

try {
    final Connection connection = connectionFactory.newConnection();
    doSomething(connection);
finally:
    connection.close();
}

If connection was not initialized by the time flow reaches finally:, connection.close(); could have been treated as a no-op. Maybe this is not that elegant, but this pattern in Java looks like a code smell to me:

ConnectionFactory connectionFactory = new ConnectionFactory();

Connection connection = null;
try {
    connection = connectionFactory.newConnection();
} finally {
    if (connection != null) {
        connection.close();
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment