前回まで、Java SE 9のjava.baseモジュールに関する新機能を紹介してきました。今回は、java.baseモジュールの中でもJavaのライブラリのベースとなる「java.lang」パッケージの新機能について紹介していきます。

文字列を表すStringクラス、内部処理を効率化

 文字列を表すStringクラスは、使う上では何も変化はありません。しかし、内部的に2種類の大きな変更が施されています。それぞれ、以下のJEPに対応します。

 JEP 254はStringクラスの内部表現に関する変更、そしてJEP 280は文字列リテラルの連結に関する変更になります。以下、それぞれについて紹介していきます。

Compact Strings

 アプリケーションをプロファイルすると、ヒープ使用の上位には必ずといっていいほどchar型の配列があります。このchar型の配列は、主にSringオブジェクトが文字列を格納するために使用している配列です。

 Javaでは文字列をUTF-16で保持しています。しかし、このことが無駄にヒープを使用している原因になっています。UTF-16では文字を表す最小単位が16ビットです。このため、8ビットで表せる文字だとしても、16ビットが割り当てられてしまいます。例えば、"abc"という文字列を表すには、内部的には16進数で「00 61 00 62 00 63」という値が保持されます。これを見ると、00の部分が気になるわけです。

 8bitで表す文字コードというと、アルファベットなどを対象にしたISO 8859-1、いわゆるLatin-1があります。そこで、Java SE 9では、ISO 8859-1に含まれる文字だけで構成される文字列であれば、UTF-16ではなく、ISO 8859-1を使用するようになりました。かなや漢字などISO 8859-1の範囲に入らない文字を含んでいる場合、従来通りUTF-16で保持されます。結果的に、前述した"abc"という文字列は16進数で「61 62 63」の3バイトで保持できるようになります。

 この変更を行うために、Stringクラスで文字列の保持用に使用していた配列が、char[]からbyte[]に変更されます。ただし、"abcあ"のようにISO 8859-1に含まれる文字とそれ以外の文字が混在する場合、すべてUTF-16で保持されます。

 日本語を扱うアプリケーションでは、ヒープ使用量の削減効果はそれほど期待できないのが残念な点です。しかし、システムプロパティなどアルファベットと数字だけで構成される文字列は意外に多くあるので、そこだけは効果があるはずです。