エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

Java14事前調査 JEP 358: Helpful NullPointerExceptions

きっかけ

そろそろJava14のリリース時期が近づいて来たので、調査。

ボリュームが多そうなので、とりあえず1個ずつ記事にまとめる。
全部一辺にやろうと思ったけど、ダレちゃいそうなので辞めた。。。

環境

$ java -version
openjdk version "14-ea" 2020-03-17
OpenJDK Runtime Environment (build 14-ea+24-1107)
OpenJDK 64-Bit Server VM (build 14-ea+24-1107, mixed mode, sharing)
$ VER
Microsoft Windows [Version 10.0.18362.592]

JDK14

JDK 14

JEP358

JEP 358: Helpful NullPointerExceptions

概要(超要約)

ヌルポのメッセージを分かりやすくしたよ

テストコード

public class JEP358 {
  public static void main(String[] args) {
    String msg = null;

    System.out.println(msg.length());
  }
}

13での実行結果

実行時にフラグ(-XX:+ShowCodeDetailsInExceptionMessages)を立てないと、以前と同じような出力になるそうなので、フラグを立てないで実行してみる。

$ javac --enable-preview -source 14 JEP358.java
$ java --enable-preview JEP358
Exception in thread "main" java.lang.NullPointerException
        at JEP358.main(JEP358.java:5)

分かるのは、5行目でヌルポになるってことだけ。
情報量が少ないため、下手するとコード読んでも分からない可能性がある。
開発者だと、そういうケースによく会うと思う。
自分も、たまにヌルポ沼にハマって抜け出せない事がある。

14での実行結果

$ javac --enable-preview -source 14 JEP358.java
$ java --enable-preview -XX:+ShowCodeDetailsInExceptionMessages JEP358
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "<local1>" is null
        at JEP358.main(JEP358.java:5)

5行目の"String.length()"を使ってるところでエラーになったってのが分かる。

2020/02/09 追記

$ javac -g -source 14 JEP358.java
$ java --enable-preview -XX:+ShowCodeDetailsInExceptionM
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "msg" is null
        at JEP358.main(JEP358.java:5)

上記の通り、コンパイル時に-gを付与することで、実行時にどの変数がnullで落ちたのか分かるようになる。
-gを付与することでデバック情報が付与されたクラスファイルができるらしい。

javac - Java プログラミング言語コンパイラ

感想

ヌルポには頭を悩ませることが多々あったので、この提案はすぐに入ってほしい。
そして、Java使ってる現場は、なるはやでこのバージョンに上げてほしい。
多くの開発者がハゲるのを防止してくれると思う。