前提知識
そもそもプログラムは、変数と呼ばれる「箱」にモノ(=値)を格納しておき、それらを取り出して別の「箱」に入っていたモノと比較したり、別の「箱」のモノと組み合わせたりというような処理ができる。「箱」というからには、その大きさには限界があったり、入れられるモノに条件があったりする。そんな変数の「箱」はプログラム上では下記のように記載して作成することができる。
型 変数名 = 初期値;
- 型…「箱」の種類を指定する
- 変数名…「箱」を特定する名前を付ける
- 初期値…「箱」にとりあえず値を入れておく(何も入れなくても何かは入ってる)
本記事で話題にしたいのは、上記の型である。この型には、記事のタイトルで示すように基本型と参照型があるのだ。簡単に説明するとそれぞれ下記のようにまとめることができる。
- 基本型…決まった大きさまでしか扱えない
- 参照型…入りきらない大きさも扱える
ここで考えてほしいのは、「参照型はどうして入りきらない大きさも扱えるのか?」という問題だ。変数と呼ばれる「箱」にはどうしたってサイズの制限があるのに、その制限を超えて扱うことができるというのはどういう仕組みなのか。その答えは、『参照型の変数その「箱」自体にモノを置いている訳ではなく、「外部に置かれているデータの場所」を保持しているに過ぎないため』である。そのことを踏まえて、Javaの変数の種類2つの説明を書きなおす。
- 基本型…「決まったサイズの値」を格納する
- 参照型…「場所」を格納する
それぞれ実際のコードも交えて説明していきたい。
基本型について
基本型の変数の「箱」には、サイズが適したモノ(=値)を格納することができる。8種類しかないので、適当に使っていれば覚えるだろう(というか使わないと覚えない)。
型名 | サイズ | 用途 |
---|---|---|
int | -2147483648~2147483647 | 一般的な数として |
long | -900京~900京 | intより大きな値を扱う |
short | -32768~32767 | あまり使わない |
byte | -128~127 | コンピュータ内で読み書きされるデータを扱うとき |
char | 0~65535 | 文字を表すコードとして |
double | ほぼ制限はない。ただし精度は15桁くらい | 一般的な少数として |
float | ほぼ制限はない。ただし精度は7桁くらい | doubleより容量を節約したいとき |
boolean | - | trueかfalse |
上記の表ではint型の最大値2147483647を超えた値、つまり「箱」のサイズを超えた値を入れようとした場合はどうなるのか? 実際に動かしてみるに限るということで、下記のようなコードを組んで動かしてみた。int intNum = 2147483647;
の部分が「int型のintNumという名前の変数を作成し2147483647を格納した」処理となる。
実行コード
public static void main(String[] arg){ int intNum = 2147483647; System.out.println(intNum);// 最大値 intNum++;// 1加算 System.out.println(intNum);// 最大値に1加算した値 }
実行結果
2147483647
-2147483648
2147483647に1を加算した値は2147483648になるはずなのだが、実際は最小値である-2147483648が入っている。その理屈は2進数による計算のアレコレで説明できるのだがここでは割愛させていただく。大事なのは基本型の変数には「決まったサイズの値」しか入らないということだ。覚えておこう。
参照型について
参照型とは「値が格納されている場所」を格納しているため、基本型のようなサイズの制限はない。javaの場合、基本型以外の型は全てこれに該当すると考えていい。ここでは参照型の一例として、文字列を入れることができるString型について、実際にコードを記載してみたい。
実行コード
public static void main(String[] arg){ String TEXT = "test"; System.out.println(TEXT); }
*1 実行結果
test
ここだけ見ると、String型を基本型のように扱っているように見えるが、String型は下記のように作成されていることを追っていくと、その中身の複雑さが分かる。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { @Stable private final byte[] value; private final byte coder; /* 一部省略 */ }
String型はただ文字列が入っているのではない。文字列が扱いやすいように様々な機能を搭載した特殊な「箱」なのである。もういっそのこと文字列を扱えるエキスパートに命令できる「箱」といってしまっていい。 例えば、箱に渡した値の文字数が知りたいというような場合、「箱」に事前に入っていたlengthメソッドというものを使って取得することが可能だ。
実行コード
public static void main(String[] arg){ String TEXT = "test"; System.out.println(TEXT.length()); }
実行結果
4
まとめ
基本型の変数には、決められたサイズの値を入れておくという基本的な機能しか搭載されていない。一方の参照型には、決められたサイズの値を入れておくというだけでなく、入っている値を取り扱うための機能も一緒に搭載されている。これはオブジェクト指向プログラムの基本的な考え方『「ある役割を持ったモノ」ごとにクラスを作って扱う』を成立させる大事な概念だ。オブジェクト指向とか関係なく、他の言語でも参照するといった考えは重要なので覚えておこう。
- 基本型…「決まったサイズの値」を格納する機能だけを持っている
- 参照型…「決まったサイズの値」を格納する機能だけでなく様々な機能を持っている
*1:System.out.printlnは引数に渡された値を画面に表示する