Stop writing code like we're in the '90s: a practical approach (PART I)

When I released Brooklyn v0.1 complaints arose from the fact that it is written in Java.
A lot of criticisms come from users that probably wrote Java code when it was born.
The language is constantly changing and I decided to use Java 8 as the primary language for Brooklyn.
I'm writing this blog post because while I was learning new features I realized that there is an enormous difference between studying something and applying what you have studied in a practical scenario.
I'll keep writing posts like that, and I want to write much more if I receive a good feedback!

Avoid null pointer exceptions
Imagine that you've a Bot interface with a method sendMessage and three classes that implements that: IrcBot, TelegramBot and RocketChatBot.
sendMessage returns a string which contains the messageId returned from the bot; the main problem is that there are bots like IrcBot which can send messages to IRC, but the protocol doesn't support messages identification.

What should you do? The first thing you can come to your mind is to return a null:
public interface Bot {
 String sendMessage(...);
}

public final class TelegramBot implements Bot {
 @Override
 public String sendMessage(...) {
  // Message is sent here

  return msgId;
 }
}

public final class IrcBot implements Bot {
 @Override
 public String sendMessage(...) {
  // Message is sent here

  return null;
 }
}
The main problem is that if your code somewhere stores the string and use it without checking if it is null, the application will crash because of a NullPointerException.

A good solution is to use the class Optional. Let's see how to use it:
public interface Bot {
 Optional<String> sendMessage(...);
}

public final class TelegramBot implements Bot {
 @Override
 public String sendMessage(...) {
  // Message is sent here

  return Optional.of(msgId);
 }
}

public final class IrcBot implements Bot {
 @Override
 public String sendMessage(...) {
  // Message is sent here

  return Optional.empty();
 }
}
Imagine now that you've sent a message with a Bot bot = new ...(); and you want to use the result of Optional<String> result = bot.sendMessage(...).
First of all, you can check if it is empty or not, and then you can do something (in this case, print the message id):

if(result.isPresent()) {
 String msgId = result.get();
 System.out.println(msgId);
}
You can also rewrite it with Lambda Expressions:
result.ifPresent(msgId -> System.out.println(msgId));
or more simply with Method References:
result.ifPresent(System.out::println);

There are cases when you don't know if a function returns a null or not.
Let's imagine that you've a static method from a library x called getFile() which returns a File object or null.
Instead of checking if it is null, you can simply write Optional<File> file = Optional.ofNullable(x.getFile()); which is the equivalent of:

Optional<File> file;
File fileNull = x.getFile();
if(null == fileNull)
 file = Optional.empty();
else
 file = Optional.of(fileNull);

Commenti

  1. Good start, I think many people have complaints against Java because they just know very old Java versions.

    RispondiElimina
    Risposte
    1. Hi :) Thank you for your feedback!
      As always we need to choose the right language for the right project :D

      Elimina

Posta un commento

Post popolari in questo blog

Brooklyn 0.1 is out there: full Telegram and IRC support