Java で StringBuilder の append するときに、null を渡すと "null" という文字列として追加されるという残念過ぎる仕様

f:id:ts0818:20190622223556j:plain

「共存在は、他者というものが現事実的に見あたらず、知覚されていないときでも、実存論的に現存在を規定しているのである。(『存在と時間』)」

はい、どうもボクです。

ハイデッガーの有名な言葉ですね。

存在論ってよく分からんけど、

www.zen-essay.com

⇧  「色即是空 空即是色」 とかも存在論 的な意味合いを含んでいるのかしら?

というわけで、null は、存在論 的にはどうなのか?っていうことを解明しようというんじゃないけど、今回も Java のお話です。

 

何故、StringBuilder の append は、null を、"null" という文字列として追加するのか?

これについては、よく分からんのだけれど...

yujisoftware.hatenablog.com

append メソッドの仕様で、「引数が null の場合、"null" という4文字が追加される」というのがあります。
この仕様について、Java 7までは "null" という文字列を追加するという実装がされていました。

これが、Java 8 では 'n', 'u', 'l', 'l' という4つの文字を追加するという実装に変わりました。

Java8 で StringBuilder/StringBuffer クラスがリファクタリングされていました。 - 地平線に行く

⇧  仕様と言われてしまうと、それまでなんだけど...。

そもそも、null ってどういうものだっけ?

Wikipedia さんによりますと、

Null(ヌル、ナル)は、何もない、という意味で、プログラミング言語などコンピュータ関係では、「何も示さないもの」を表すのに使われる。同様のものに、nil が使われることもある。他の名前のこともある。

Null - Wikipedia

⇧  「何もない」 ものって 位置づけのはずなんだけど...

そんじゃあ、何故に、StringBuilder の append は、「何もない」 ものである null というものを、"null" という文字列としてわざわざ存在させるのか?

 

www.symmetric.co.jp

C言語には上述した通り、言語仕様上、文字列の概念や配列の長さの概念を持っていない。そこでC言語では、連続する「0x00」以外の文字と、終端を表す「0x00」とで構成されるデータを使用し、「0x00」までの部分を文字列とみなしている。

やっぱり苦労するC言語のNULL文字’¥0′ | | 株式会社シンメトリック公式ブログ

⇧  上記サイト様で仰っておられる、C言語のNULL文字という概念に影響されているということなんだろうか?

まぁ、でも、Java は、文字列の概念が存在するのだが...

 

どうやら、StringBuilder の作りが原因らしい...

beginnersbook.com

The reason is explained in the documentation of the append() method from javadoc:
public StringBuilder append(String str): Appends the specified string to this character sequence.
The characters of the String argument are appended, in order, increasing the length of this sequence by the length of the argument. If str is null, then the four characters “null” are appended.

StringBuilder append() null values as "null" String

⇧  append した分だけ、StringBuilderのオブジェクトの長さが加算されていくらしく、append メソッドの引数として与えられたオブジェクトの長さを取得する必要があるため、null.length だとNullPointerException が発生してしまうから、それを回避するためってことですかね?

だとしたら、残念過ぎる仕様なんですが...

あくまで、推測でしかないけど、もし、これが本当の理由だとしたら、StringBuilder を作った人、ご乱心したとしか思えないんだが...

っていうか、普通に考えて、どっちにしろ、null が渡されてきてるんだから、足しちゃダメでしょう...。

 

 

実際に残念な仕様を確認

というわけで、何も存在しないはずである、null というものを、"null" という文字列として存在せしめる、StringBuilder の append の錬金術を見てみますか。

Eclipse を起動し、適当にJavaプロジェクト、クラスを作成。

f:id:ts0818:20190622231828p:plain

そんで、ソースコードはこんな感じ。
 

package main;

public class TestNullValue {

  public static void main(String[] args) {
    // TODO 自動生成されたメソッド・スタブ
    StringBuilder sb = new StringBuilder();
    String nullValue = null;
    sb.append("令和");
    sb.append(nullValue);
    sb.append("年");
    System.out.println(sb.toString());
  }

}
    

そんでは、「実行(R)」>「Javaアプリケーション」で。

f:id:ts0818:20190622232116p:plain

f:id:ts0818:20190622232225p:plain

⇧  はい、見事に、null が、"null" 文字列として追加されています!

存在しないものを、存在させ、文字の長さとしても加算しているという、無から有を作り出す、まさに錬金術!っていうか駄目駄目やん!

というわけで、StringBuilder の append を使うときは気を付けたいという話でした。

まぁ、何ていうか、プログラミングも内部構造とかは結構、適当なんですかね...こういう現象を目の当たりにしてしまうと、頑張って勉強する気が起きないですね...

今回はこのへんで。