Work as a team! Face Null head-on in Java

I apologize for inventing the null reference at the 2009 conference.

That's my mistake, worth a billion dollars.

Null This is a hate problem that developers who use insecure languages are always plagued with. Computer scientist [Antony Hoare | wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%B3%E3%83%88%E3%83%8B% As E3% 83% BC% E3% 83% BB% E3% 83% 9B% E3% 83% BC% E3% 82% A2) said above, it is a technical debt woven into the language. It is no exaggeration to say.

In modern new development, null insecure languages are no longer legacy languages | Qiita The idea of avoiding null insecure languages themselves as in the article There will be. However, there are still situations where you have to choose a language that is not Null-safe for a variety of reasons.

So, this time, I will think about the method for facing Null in Java.

スクリーンショット 2018-06-20 19.31.07.png

Precautions for reading

――The countermeasure plan has a "recommendation level", but it is a personal impression based on experience. ――The recommendation level when incorporating in a team is shown in 3 stages (: star: ~: star :: star :: star :)

Measure

JSR-305 A group of annotations defined for Software Defect Detection as a Java specification.

Therefore, it is not an annotation expected to work in Runtime, but a specification defined as a ** auxiliary function ** at the time of development (for example, support in IDEs such as Find Bugs and IntelliJ).

Declare if the return type is null

Recommendation level:: star :: star:: star:

import javax.annotation.Nullable;

@Nullable
public String createText() {
    // ...
import javax.annotation.Nonnull;

@Nonnull
public String createText() {
    // ...

It is very important to be able to use the check support function, but I felt that the effectiveness would be maximized in the following points when working as a team.

--The intention of each method of the designer / implementer can be clearly left. -Improved quality at the time of review as a side effect --Reduces the effort of implementers using methods to consider null --Reduced unnecessary null checks

Declare whether to allow null in the argument

Recommendation level:: star:

import javax.annotation.Nullable;
import javax.annotation.Nonnull;

public String createText(@Nonnull String id,
                         @Nullable String option) {
    // ...

While you can get the same advantages as "declare whether the return type is null ", the following disadvantages are conspicuous for the team.

--It is troublesome to add all the arguments ――Because it is troublesome, it is easy to become a mere corpse --The argument goes into the annotation festival state, and visibility drops.

Java 8+ standard ʻOptional`

ʻOptional suggests null` as the return type

Recommendation level:: star:

import java.util.Optional;

public Optional<String> getText() {
   // ...

Java 8 ʻOptional` is mentioned in many articles, so I won't go into details. The reasons why we do not recommend it here are as follows.

--ʻOptional` type is not a Serializable class, so its usage is limited. --Rules are likely to break in cases where libraries (especially O / R Mapper type) are not supported.

■ Reference

-Java 8 "Optional" ~ How to deal with null in the future ~ -Summary of stories and usage of Optional not Serializable

Assertion programming

"Assertion programming" that checks the preconditions introduced in Master Programmer. It's very valuable because it allows you to leave the designer / implementer's "higher level concept" as code.

Test program assumptions with ʻassert`

Recommendation level:: star :: star:

private String createText(String id) {
    assert (id != null) : "id must not be null.";
    // ...

A typical example of assertive programming in Java is ʻassert`. However, you should be aware of the following points in the code (Programming with assertions | oracle.com Excerpt from assert.html)

■ Enable and disable assertions ** By default, assertions are disabled ** at run time. You can use the two command line switches to enable / disable assertions. Use the -enable assertions or -ea switches to enable assertions at various levels of detail.

It can be read that ʻassert` is just an auxiliary means for the implementer's assertion, not for raising an exception in the runtime of the product code. Also, if you read the official document carefully, it will contain important information such as treatments that have side effects, so you need to think carefully about what points to use when adopting.

Leverage library assertions

Recommendation level:: star :: star:: star:

import org.springframework.util.Assert;

public String createText(String id) {
    Assert.notNull(id, "ID must not be null.");
    // ...

For Spring framework ʻorg.springframework.util.Assert` Use is that.

Unlike Java Assertion, it raises an exception even at Runtime. It's a simplification of null checking, but it also works with the Runtime, so you can leave a very strong statement of intention in your code.

Indirect null defense

Declare the variable as final to make it Immutable

Recommendation level:: star :: star:

public String createText(final String id) {
    // ...
public String createText(String id) {
    final String prefix = something(id);
    // ...

The use of final does not seem to be directly related to null. However, in combination with the non-null guarantee in Assertion, you can almost completely guarantee non-null in your method. As a result, you can confidently delete unnecessary processing such as "I don't know what will come, so check" null for the time being "in the intermediate processing.

Make Collection Immutable

Recommendation level:: star :: star:

Java standard
import java.util.Collections;

public String createText() {
    List immutables = Collections.singletonList("value1", "value2");
    // ...
import java.util.Collections;

public String createText() {
    Map<String, String> immutables = Collections.singletonMap("key1", "value1");
    // ...
import java.util.Collections;

public List<Store> fetchStores() {
   List<Store> stores  = findAll();
   
   return Collections.unmodifiableCollection(stores);

Guava

import com.google.common.collect.ImmutableMap;

public String createText() {
    Map<String, String> immutables = ImmutableMap.of("key1", "value1", "key2", "value2");
    // ...
import com.google.common.collect.ImmutableList;

public String createText() {
    List<String> immutables = ImmutableList.of("value1", "value2");
    // ...

It's a fairly local defense when it comes to immutable collections.

It reduces the risk of mixing null elements into a collection once created, with the goal of caring for null exceptions in subsequent intermediate processing. It's sober, but it should be incorporated as much as possible.

example

Let's see how much the amount of information actually differs before / after application.

before

public class StoreService {
    
    public Store fetchStore(String storeId){
        // ...
    }

    public List<Store> fetchSisterStores(String storeId){
        // ...
    }

    public List<Coupon> fetchCoupons(String storeId,
                                         List<Category> categories){
        // ...
    }
}

after

public class StoreService {

    @Nonnull
    public Store fetchStore(final String storeId) {
        Assert.notNull(storeId, "store-id must not be null.");
        // ...

    }

    @Nullable
    public List<Store> fetchSisterStores(final String storeId) {
        Assert.notNull(storeId, "store-id must not be null.");

        // ...
    }

    @Nonnull
    public List<Coupon> fetchCoupons(final String storeId,
                                     final List<Category> categories) {
        Assert.notNull(storeId,    "store-id must not be null.");
        Assert.notNull(categories, "categories must not be null.");

        // ...
    }
}

Isn't it a more expressive code? Just by reading a few lines before and after the signature, you can instantly pick up most of the examples, and the code is user-friendly.

From the reviewer's point of view, the difference in the specifications of the List type returned byfetchSisterStores (...)andfetchCoupons (...)is more apparent, and the quality of the review is likely to improve.

Summary

Choose the null measures as a team and cut down the technical debt caused by null to the utmost limit! And let's realize the following merits with the whole team!

--Improved code readability --Improved review quality --Reduced nights when wetting pillows with Nullpo

Let's have a good null life!

Recommended Posts

Work as a team! Face Null head-on in Java
Java11: Run Java code in a single file as is
Find a subset in Java
Read WAV data as a byte array in Android Java
Do Scala Option.or Null in Java
3 Implement a simple interpreter in Java
I created a PDF in Java.
A simple sample callback in Java
Get stuck in a Java primer
How arrays work in Java (illustration)
About returning a reference in a Java Getter
What is a class in Java language (3 /?)
When seeking multiple in a Java array
[Creating] A memorandum about coding in Java
Output Notes document as XML document in Java
Java creates a table in a Word document
Java creates a pie chart in Excel
What is a class in Java language (1 /?)
What is a class in Java language (2 /?)
Create a TODO app in Java 7 Create Header
Try making a calculator app in Java
Implement something like a stack in Java
Split a string with ". (Dot)" in Java
Creating a matrix class in Java Part 1
I made a primality test program in Java
GetInstance () from a @Singleton class in Groovy from Java
Two ways to start a thread in Java + @
Read a string in a PDF file with Java
A story about the JDK in the Java 11 era
How to display a web page in Java
Measure the size of a folder in Java
Code to escape a JSON string in Java
Try to create a bulletin board in Java
A note when you want Tuple in Java
I wanted to make (a == 1 && a == 2 && a == 3) true in Java
I wrote a primality test program in Java
I made a rock-paper-scissors game in Java (CLI)
Display text as ASCII art in Java (jfiglet)
A bat file that uses Java in windows
How to hide null fields in response in Java
A quick review of Java learned in class
I wrote a prime factorization program in Java
[Java] Something is displayed as "-0.0" in the output
Pass the condition to be used in the Java8 lambda expression filter () as a parameter