String型から不変クラスを学ぶ【Java】
String型は参照型であるにも関わらず、値渡しされているかのような振る舞いをする。...ふと、今更ながら「なんで?」と思った次第。
参照型はクラス型・インターフェース型・配列型と3つに分類でき、String型はクラス型。
実際に内部ではStringクラスとして実装されているわけだが、このStringクラスは「不変クラス(イミュータブル, immutable)」として実装されている。
これが、参照型なのに値渡しされてるように見える理由だった。
// コード(1) // Stringクラスのメンバ変数 private final char value[]; private final int offset; private final int count; // ...略... public String(char value[]) { int size = value.length; this.offset = 0; this.count = size; this.value = Arrays.copyOf(value, size); // <- 防衛的コピーで不変クラスを実現 }
コード(1)はStringクラスの実装の一部。これを踏まえた上でコード(2)について考えてみる。
// コード(2) String str = "abc"; // これは次の2行と同じ // char data[] = {'a', 'b', 'c'}; // String str = new String(data); // <- コード(1)のメソッドが使用される
コード(1)を見ると、char型の配列を渡し、それをコピーして新たな配列を生成していることで、他のオブジェクトからの変更可能性を排除していた。
このように引数として受け取ったオブジェクトから値を取り出して、それをもとに新しいオブジェクトを生成することを「防衛的コピー」という。
Stringクラスの実装には、随所にこの防衛的コピーが施されている。
防衛的コピーは、特に、参照型のフィールドや参照型引数のメソッドを持つ不変クラスを作る上で重要な手法なので、しっかりと覚えておく。
Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで
- 作者: 谷本心,阪本雄一郎,岡田拓也,秋葉誠,村田賢一郎,アクロクエストテクノロジー株式会社
- 出版社/メーカー: 技術評論社
- 発売日: 2017/04/18
- メディア: 大型本
- この商品を含むブログを見る
EFFECTIVE JAVA 第2版 (The Java Series)
- 作者: Joshua Bloch,柴田芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2014/03/11
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (10件) を見る