| byte | short | char | int | long | float | double |
| 1バイト | 2バイト | 2バイト | 4バイト | 8バイト | 4バイト | 8バイト |
論理値のデータを扱う型が boolean型です。 値は true もしくは false です。 true と false は Javaの予約語です。 数値型のデータにキャストしたりはできません。 void型は実体が存在しない型です。 メソッドの返値が存在しないことを示すために用います。
原始型はクラスではなく「裸のデータ」です。
このようなデータの存在を許すということは、
純粋なオブジェクト指向の立場からは多少逸脱しています。
原始型の存在を根拠に「Javaは 100%純粋なオブジェクト指向ではない」
という主張も成り立つかもしれません。
ただし、Javaの原始型は決してなし崩し的に導入されたものではありません。
その証拠に、
JDKの java.langパッケージには9個の原始型のそれぞれに対応して9個のクラスが
ちゃんと用意されています。これらは「ラッパ(rapper)クラス」と呼ばれます。
原始型のデータを「包み込む」ようにして覆い隠し、
外部とのやりとりの機能を提供してくれるからです。
ラッパクラスの名称は下記のように原始型にほぼ対応します。
(ただし char に対応するクラス名は Character、
int に対応するクラス名は Integerです。)
厳密なオブジェクト指向の立場に立って「美しいプログラム」を組みたいと思ったら、
これらのラッパクラスを使用すればいいでしょう。
ただし、それは必ずしも現実的な選択ではありません。
数値や論理型のデータは非常に頻繁に用いますから、
実際にソースコードを書く立場になれば原始型を用いた方がはるかに効率的です。
また開発されたアプリケーションの実行段階でも、明らかに効率面で有利です。
Javaは理論的な純粋さよりも現実面を優先させる選択をしたと言えるでしょう。
| ラッパクラス名 | Byte | Short | Character | Integer | Long | Float | Double | Boolean | Void |
|---|---|---|---|---|---|---|---|---|---|
| 対応する原始型 | byte | short | char | int | long | float | double | boolean | void |
なお上記のラッパクラスは、 原始型を取り扱うためのさまざまな便利な機能も提供してくれます。 たとえば Intergerクラスは文字列を数値に変換したり、 16進表現を 10進表現に変換したりする機能を提供します。 Javaでラッパクラスを利用するのは、 むしろそうした便利な機能を呼び出すための場合が多いでしょう。
さて、原始型について最後に説明しておきたいことは、データの寿命の問題です。
原始型のデータのためのメモリーは、
それがプログラム内で宣言された時点で確保されます。
それが宣言されたメソッドもしくはブロックの処理が終了すると、
自動的にその寿命は尽きます。
メソッド(コンストラクタも含む)の引数に与えられた原始型のデータは、
メソッドが呼び出されたると同時にメモリー領域が確保され、
メソッドの呼び出し側で与えられた値がコピーされます。
その寿命はやはりメソッドの処理が終わるまでです。
(呼び出し側のオリジナルのデータは消滅しません。)
またクラスのフィールドとして宣言された原始型のデータは、
そのオブジェクトが生成された時にメモリが確保され
オブジェクトと同じ寿命を持ちます。
(ただし最後に説明する static宣言されたデータは別です。)
以上のルールは比較的理解しやすいものでしょう。
ソースプログラム内のブロック構造が、
そのままデータの寿命に対応しているからです。
また原始型のデータの寿命に対応するブロックは、
変数名が有効な範囲とも完全に一致しています。
public class PrimitiveData {
public int x; // x の寿命はオブジェクトが消滅するまで
public void calulate( int y ){ // y の寿命はメソッドを抜けるまで
int z; // z の寿命はメソッドを抜けるまで
for( int i=0; i<10; i++ ) { // i の寿命はこのブロックを抜けるまで
z += i;
}
}