2.11. java.lang.String。みんな使っている文字列クラス。

javaの文字列クラスの代表です。

どこでもみんな使っているけど、改めてじっくりと構造を眺めてみると発見があるかも。

2.11.1. クラス図へ変換

では、早速クラス図にしてみましょう。

UML変換くんを実行。

> touml .\java\lang\String.java

※java1.8コード

まず、パッケージ図はこれです。Stringはこの範囲のpackageに収まっています。

Integerと比較するとだいぶ広範囲に他のpackageを使っています。

../_images/java.lang.String.image001.jpg

java.nioはnew I/Oの略だそうで、新入出力です。

regexは正規表現関連です。

libcore.utilはCharsetUtilsクラスを使って文字コード処理をしています。

次にクラス図です。

../_images/java.lang.String.svg

元の図は大きいので小さく切り取って、見ていきます。

2.11.2. 継承

../_images/java.lang.String.image002.jpg

まずは、Serializableを実現しています。Serializableはクラスのインスタンスをシリアライズすることができる目印になっています。

シリアライズで来るとインスタンスを帆ファイル保存とかもできて何かと便利です。

※自分で作ったクラスをシリアライズしたい場合には、これを実現しているクラスしかフィールドにもてないので、シリアライズしたい場合にはよく確認しましょう。

CharSequenceも実現しています。これは文字列関連のクラスの共通のインタフェースです。

文字列に特化したメソッド「+length():int」とか、「+charAt(index:int):char」などはCharSequenceをオーバーラードしたものです。

Comparable<String>はIntegerでも出てきました、比較用のインタフェースです。文字列も比較できるのでこれを実現しています。

2.11.3. フィールド

../_images/java.lang.String.image003.jpg

「-value:char[]{readOnly}」は文字列の本体を保持しています。

「-count:int{readOnly}」とかは文字列の文字数ですね。

「-serialVersionUID:long=-6849794470754667710...{readOnly}」

「-serialPersistentFields:ObjectStreamField[]=new ObjectStreamFiel...{readOnly}」

このへんは、シリアライズのときに使います。

「+CASE_INSENSITIVE_ORDER:Comparator<String>=new CaseInsensitiveC...{readOnly}」は文字列比較のときに、大文字小文字を無視して大小を比較するときに利用するそうです。

2.11.4. メソッド

../_images/java.lang.String.image004.jpg

このへんは、コンストラクタです。new String(..)でインスタンスを生成時に利用されます。

「+String(ascii:byte[],hibyte:int):void」が気になったのでしらべみたところ、hibyteで設定した数値をasciiの上位バイトに書き込む処理をしていました。

※「hibyte <<= 8」して「value[i] = (char)(hibyte | (ascii[i])」する感じです。

※きっと使いどころがあるのでしょう。

../_images/java.lang.String.image005.jpg

このへんは、文字数の取得とか、文字列が空かどうかをチェックできます。

../_images/java.lang.String.image006.jpg

このへんは、文字(char、byte、文字配列)として取得する機能。

../_images/java.lang.String.image007.jpg

この辺りは、文字列同士を比較する関連。

../_images/java.lang.String.image008.jpg

範囲を指定して部分文字列を含むかをチェックする関連。

../_images/java.lang.String.image009.jpg

範囲を指定して部分文字列を抜き出す関連。

../_images/java.lang.String.image010.jpg

この辺りは、文字列置換や、正規表現を使った文字列検索の機能。

../_images/java.lang.String.image011.jpg

文字列を分割して取得する機能。

../_images/java.lang.String.image012.jpg

文字列結合の処理。

../_images/java.lang.String.image013.jpg

大文字を小文字に変えたり、小文字を大文字変えたりする機能。

../_images/java.lang.String.image014.jpg

文字列の前後のスペースを除去した文字列を生成する。

「 aaa 」のよう前後に無駄なスペースがある場合に切り取り「aaa」とする。

../_images/java.lang.String.image015.jpg

c言語のsprintf関数のような、フォーマット文字列から文字列を作成する機能。

cユーザーにうれしい機能。

../_images/java.lang.String.image016.jpg

色々な型を文字列に変換する機能。

こういうものが標準で準備されているのは便利ですね。

../_images/java.lang.String.image017.jpg

これは何かと調べてみたところ、どうもIngeterのキャッシュのような機能である。一度使った文字列を内部に保持して使いまわすらしい。

※高速化のためなどだろうか、以下のように処理がnativeになっている。現状中身が見られないので詳細はよくわからない...かも。

public native String intern();

※intern:(一定の区域内に)拘禁する、抑留する

2.11.5. 内部クラス

../_images/java.lang.String.image018.jpg

CaseInsensitiveComparatorは文字列比較用のインタフェースComparatorを実現したクラスです。

これを使って比較すると、大文字と小文字を区別せずに比較できます。

メソッド「+compareToIgnoreCase(str:String):int」の中で使われています。

2.11.6. 関連、例外

../_images/java.lang.String.image019.jpg

2.11.6.1. UnsupportedEncodingException

例外「UnsupportedEncodingException」はその文字コードはサポートしてないよという例外です。

「+String(bytes:byte[],offset:int,length:int,charsetName:String):void」メソッドでcharsetNameがサポート外の文字コードの時に発生してました。

2.11.6.2. ObjectStreamField

ObjectStreamFieldはシリアライズ用のクラスです。

フィールドの「-serialPersistentFields:ObjectStreamField[]=new ObjectStreamFiel...{readOnly}」で

使われていました。ここにフィールド名を追加すると、非対象のフィールドもシリアライズの対象にできるそうです。

2.11.7. まとめ

Stringクラスはひとつのクラスにかなりの機能が組み込まれていました。

正規表現、format文字列出力なんかもあり、とても多機能なクラスでした。

あとIntegerとかもそうですが、javaのクラスは結構キャッシュの機能を持っているのですね。