MogLog

メモというか日記というか備忘録というか

『パーフェクトJava』学習ノート: 文字と文字列

■ 文字列について
文字列は、プログラミングで扱うデータ型の1つである。
文字列は文字の並びとして定義され、文字列中の一つ一つの文字は先頭から数えるインデックス(添字)で参照する。例えば、「abc」という文字列があれば、0番目の文字列として「a」、1番目の文字列として「b」というように取り出す事が可能。

■ 文字列と配列について
文字列の特徴は配列の特徴と似ている。事実、内部的には文字列は文字の配列である。その一方で、Javaは文字列を「文字の配列のように見えない工夫(抽象化)」をしている。そのため、Javaで文字列を扱うプログラミングをする場合、文字の配列という意識は捨てること。

■ 文字列のimmutableという特性について
Stringオブジェクトは変更不能(immutable)である。例えば「abc」という文字列があった場合、先頭文字の「a」を参照することはできるが、変更することはできない。

■ StringクラスとStringBuilderクラスの違いについて
Javaで文字列を扱う基本的なクラスは「Stringクラス」である。ただし、Stringクラスは文字列の内容を変更できない読み込み専用の文字列クラスである。変更可能な文字列が欲しい場合は「StringBuilderクラス」を利用することになる。

リテラル表記について
ソースコード上に書いた値が値のまま評価される仕組みのこと。
以下のコードでは、コード中のStringやsといった文字列は型や変数の名前であり、実行時に“String”や”s”の文字列としての働きを持たないのに対し、ダブルクオートで囲んだ”0123456789”は、この文字の並びのまま実行時に意味を持つ。
Javaの文字列リテラルは暗黙にStringクラスのオブジェクトを生成する。この仕組みにより、文字列リテラルを変数に代入するだけで、変数sはStringオブジェクトを参照する関係になる。

// 文字列リテラルを利用した場合の変数への値の代入
String s = "0123456789";
// 文字列リテラルを利用しない場合の変数への値の代入(非推奨)
String s = new String("0123456789");

■ Objectクラスについて
ObjectクラスはJavaの全てのクラスに共通した基底クラスである。

■ valueOf系メソッドとparse系メソッドについて
valueOf系メソッドとparse系メソッドは同じような働きをする。内部の実装に些細な違いはあるものの、両方のメソッドを混在させるくらいならば、はじめからparse系メソッドを使ってしまった方が、考えることが減る。プログラミングにおいて些細なことは決め事にして頭から追い出すのは重要なことである(parse系メソッドのほうが若干効率が良いので、parse系を薦めている)。

■ 同一性と同値性について
同一性と同値性という性質をJavaは持つ。この違いを理解していないと、予期せぬバグに苦しめられることになるので注意。

Javaにおける「文字」について
Javaの世界では、文字はそれぞれに一意な値を割り振られ、内部的には文字を数値として扱う(これは、コンピュータの世界にも言えること)。

Javaにおける文字コードについて
Javaの世界の文字コードUnicodeである。

Unicodeについて
Unicodeの1文字あたりのバイト数は2バイト(16bit)である。Javaで扱う全ての文字には対応する16ビットの数値が存在する。

■ char型について
16ビットの数値を表現する型が基本型のchar型である。char型は16ビット長で正の整数値を表現する。

■ 文字列と文字について
文字列と文字は違う。Javaプログラミングの理想は、文字列を意識して、文字を意識しないことである。しかし、実際にはその理想に反する必要も出てくる。これらを踏まえた上でパーフェクトJavaの著者が進める手法は以下。「効率性に問題が無い限り、文字単位の処理は避け、文字列としての処理を意識してください。実行速度が問題になる場合には、文字を直接扱ってください。理想を追いすぎて、遅いコードを書かないようにしてください。文字単位で処理する場合、その処理はクラスやメソッドの中に隠蔽してください。」

■ ダブルクオートとシングルクオートの違いについて
文字列リテラルをダブルクオートで囲うのに対し、文字リテラルはシングルクオートで囲う。シングルクオート内には、Unicode文字を1文字だけ書くことができる。

■ 文字列リテラルと文字リテラルについて
文字列リテラルが暗黙的にStringクラスのオブジェクトを生成するのに対し、文字リテラルはchar型の数値を生成する。

■ 文字処理の歴史と傾向について
歴史的には、バイトはコンピュータによる文字処理で1文字を表現するデータ量であった。バイトと文字を同一視する考えは今でも続いている。英数字だけを使う限りは、8bit長の範囲で文字を表現できるからである。しかし、国際化の観点からバイトと文字を同一視する考え方は否定されつつある。Javaの言語仕様はバイトと文字が異なることを前提にしている。文字を表現する型はchar型で、16ビット長である。また、バイトは8ビット長でbyteという型である。

■ ASCIIとUnicodeについて
ASCII文字は8ビット長。Unicodeは16ビット長。ただし、Unicodeの最初の128文字はASCIIコードと同じ文字になっている。例えばASCIIコードでは「a」を「01100001」と表現するが、Unicodeでは「0000000001100001」と表現する。要するに、Unicodeで表現した英文字の場合、1バイトを単純に切り落とすだけで、ASCIIコードになる。