Friday, April 22, 2016

Create a GUID in Java

Some software development tasks need a way to generate unique identifiers. I saw several homegrown solutions, but Java 5 makes the process a breeze. It contains class UUID which can generate type 4 (pseudo randomly generated) unique identifiers. Here is a simple example:
package net.softwaregeek;

import java.util.UUID;

public class UUIDMain {
    public static void main(final String[] args) {
        System.out.println(UUID.randomUUID());
    }
}
The code is self-explanatory. It generates a unique identifier and prints it to console. Class UUID contains several other useful methods which I encourage you to explore on your own.

Thursday, April 7, 2016

Change Editor for Git Commit Messages

Git is a very powerful tool especially when used from a console. Obviously committing changes is a pretty common task which includes editing commit messages. If a message is short it is easy to specify it via -m option:
$ git commit -m "my commit message"
But what if you have a long list of changes and you need a descriptive well-formatted commit message? It would be cool to write it in your favorite text editor, wouldn't it? Is there a way to tell Git which editor to use? Yes, it is. According to the docs for git-commit:

"The editor used to edit the commit log message will be chosen from the GIT_EDITOR environment variable, the core.editor configuration variable, the VISUAL environment variable, or the EDITOR environment variable (in that order)."

I'm a Vim fan and I stick to the core.editor configuration variable. So, here is my preferred way to configure commit message editor:
$ git config --global core.editor "vim"
Now I can omit -m option and enjoy editing commit messages in Vim :)

Wednesday, April 6, 2016

Rename a Remote Branch in Git

In the previous post I described how to rename a local branch in Git. Now let's take a look how to rename a remote branch. The process is a bit more complicated than with a local one and consists of the following steps:
  1. Create a new local auxiliary branch with the desired name.
  2. Push newly created local branch to the remote repository.
  3. Delete the original branch from the remote repository.
  4. Delete an auxiliary local branch (optional).
Let's take a look at a simple example. Suppose I have a Git repository which contains a couple of remote branches in it:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
Suppose that branch release-v1.0 was created by mistake and I actually want it to be named release-v1.1. Let's perform the first step and create an auxiliary branch:
$ git branch release-v1.1 origin/release-v1.0
Let's see what we have locally and remotely:
$ git branch
* master
  release-v1.1
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
Now it is time to push our new local branch to the remote repository:
$ git push origin release-v1.1
The above command creates a new remote branch named after the local one created on the previous step:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.0
  origin/release-v1.1
Let's delete the old remote branch:
$ git push origin :release-v1.0
Now we have the following remote branches:
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.1
Optionally we can get rid of the auxiliary local branch:
$ git branch -d release-v1.1
Let's take a look at the final result:
$ git branch
* master
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
  origin/release-v1.1
Here are all the commands in one place for convenience:
$ git branch release-v1.1 origin/release-v1.0
$ git push origin release-v1.1
$ git push origin :release-v1.0
$ git branch -d release-v1.1

Rename a Local Branch in Git

From time to time I have typos crept in the names of Git branches I create. Certainly it is possible to delete a branch and create a new one with corrected name. However Git allows for combining two steps into a single one. Here is a simple way to rename a local branch:
git branch -m <old-branch-name> <new-branch-name>
If a branch which should be renamed is the current one then the command above can be further simplified to the following:
git branch -m <new-branch-name>
If a branch named <new-branch-name> already exists -M option (which is actually just a shortcut for -m -f) can be used to force rename:
git branch -M <old-branch-name> <new-branch-name>
Type in the following command to get more information:
git help branch

Monday, April 4, 2016

How to Avoid Null Checks in Java

I suppose every Java developer wrote checks similar to the following many times:
if (obj != null) {
    // ...
    obj.doSomething();
    // ...
}
Sometimes such code seems reasonable and its usage can be justified. However more often than not there are better ways to code which allow for avoiding null checks altogether. In this article I want to present several helpful approaches which can make life of a Java developer easier in this regard. All of them use core Java only. Let's get started.

Using Assertions

Assertions were introduced in Java starting from version 1.4. However it looks like they are still underused. Here is an example which checks via assertions whether an argument belongs into required numerical range:
package net.softwaregeek;

public class Main {
    public static void main(final String[] args) {
        doSomething(-300);
        // ...
    }

    private static void doSomething(final int arg) {
        assert (arg > -100) && (arg < 100);
        // ...
    }
}
In the above example arg is out of range hence AssertionError will be thrown:
Exception in thread "main" java.lang.AssertionError
 at net.softwaregeek.Main.doSomething(Main.java:9)
 at net.softwaregeek.Main.main(Main.java:5)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
In order to add some details to the AssertionError a message can be attached to the assertion. It should be separated by colon from the assertion condition:
package net.softwaregeek;

public class Main {
    public static void main(final String[] args) {
        doSomething(-300);
        // ...
    }

    private static void doSomething(final int arg) {
        assert (arg > -100) && (arg < 100) : "arg is out of range";
        // ...
    }
}
This time stack trace contains descriptive error message:
Exception in thread "main" java.lang.AssertionError: arg is out of range
 at net.softwaregeek.Main.doSomething(Main.java:10)
 at net.softwaregeek.Main.main(Main.java:5)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:606)
 at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Going back to null checks, the code similar to the following can be used to avoid them:
private void doSomething(final Date date) {
    assert (date != null) : "date cannot be null";
    // ...
}
Parentheses are optional, but in my opinion they improve readability by emphasizing the assertion condition, so I'll keep them.

The last but not the least: assertions are disabled by default. In order to enable them -ea option should be given to the JVM. Assertions can be enabled/disabled globally or per class/package. Take a look here for more information.

I intentionally used private methods in the above examples to emphasize an important point. Since assertions are disabled by default and can be selectively turned on/off it makes sense to use them for testing purposes or in private methods in the environments which you can control. In a production environment assertions can be disabled and they will be ignored by JVM. Hence they don't work well for checking invariants of public methods. More details on this can be found in Item 38 of Joshua Bloch's Effective Java book. Let's take a look at the next option.

Using Objects.requireNonNull()

A lot of improvements and enhancements were introduced in Java 7. One of them is Objects utility class. Among other goodies it contains methods that streamline null checks. Here they are:
public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj;
}

public static <T> T requireNonNull(T obj, String message) {
    if (obj == null)
        throw new NullPointerException(message);
    return obj;
}
As you can see the difference between the latter and the former is an error message which is passed to the exception constructor. So the code similar to the following can be used to make sure the object in question is not null:
public void doSomething(final Date date) {
    Objects.requireNonNull(date, "date cannot be null");
    // ...
}
Looks good, but we can do even better...

Using Optional Type

In Java 8 class Optional was introduced. The idea behind it is known for a long time in the functional programming world. An instance of Optional<T> is either a wrapper for an object of type T or for no object at all. Let's take a look at several usage examples:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("Hello World"));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        str.ifPresent(System.out::println);
    }
}
The above example demonstrates Optional#ifPresent method. It takes an implementation of Consumer interface and performs provided action if the Optional instance wraps an object.

If return value is needed then Optional#map method can be used. It takes a Function implementation and returns an Optional instance. Here is an example:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("   Hello World   "));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        Optional<String> trimmed = str.map(String::trim);
        trimmed.ifPresent(System.out::println);
    }
}
Another useful method is Optional#orElse. It returns wrapped object if it exists. Otherwise default value (passed as argument) is returned:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("Hello World"));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        System.out.println(str.orElse("default value"));
    }
}
Making a default value might take a lot of computational work. In this case it makes sense to delay default value computation until it is really needed. This can be done via Optional#orElseGet method. It takes a Supplier implementation as a parameter which will be invoked only in the case an instance of Optional doesn't wrap some object:
package net.softwaregeek;

import java.util.Optional;

public class Main {
    public static void main(final String[] args) {
        doSomething(Optional.of("Hello World"));
        doSomething(Optional.empty());
    }

    private static void doSomething(final Optional<String> str) {
        System.out.println(str.orElseGet(() -> {
            double result = 0;
            // do some time-consuming calculation
            return String.valueOf(result);
        }));
    }
}
There are other helpful methods implemented in the Optional class. Take a look at documentation for complete details. One final note: make sure the code you write with Optional objects does not resemble the code with null checks:
private static void doSomething(final Optional<String> str) {
    if (str.isPresent()) {
        final String value = str.get();
        // do something with value
    }
}
The code above neglects the true power and beauty of Optional objects. Such coding patterns should be avoided.

Conclusion

The idea of null reference might rarely be in handy (e.g. when coding some low-level stuff in C), but most often it should be avoided. Tony Hoare - the inventor of null reference - said the following about it: "I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years."

I hope this article will help you to avoid a lot of billion-dollar mistakes :)

Thank you for reading!
Andrii