【Java入門】第8回 変数とデータ型|Javaのプログラムで利用できる値の種類
2024.06.07
Javaの開発環境ができたら、プログラムを始めましょう!
まずはプログラムの基本中の基本、「変数」とJavaのデータ型について説明します。
目次
Javaの変数
変数とは?
Javaなどのプログラミング言語では、プログラム上でデータを格納&保持する場所として、変数を使用します。これは値を保管する箱のようなものです。
変数には、数値や文字列など様々なデータや値を保管でき、保管された内容をあとから取得することが可能です。
変数を定義する際は「型」「変数名」の順に記述します。このように変数を定義することを、「変数宣言」や「変数を宣言する」と呼びます。
変数を宣言する位置はclassの中である必要があります。(メソッドの中でも可)
public class HensuMain {
int num = 100; // int型の変数numを宣言
public static void main(String[] args) {
String str = "Hello"; // String型の変数strを宣言(main メソッドの中)
}
}
ローカル変数
変数は、プログラム上の宣言した位置や、アクセス修飾子と呼ばれるもので、プログラム上のどこから参照(値の設定や取得)できるかが変わります。
一連のプログラム上のどこからでも参照できる変数を「グローバル変数」と呼ぶのに対して、特定の範囲やプログラム上からのみ参照できる変数のことを「ローカル変数」と呼びます。
例として、メソッドの中で宣言した変数はメソッドの中だけでしか参照できません。
また、if ブロックや for ブロックなどの中で宣言した変数は、メソッドの中でもさらに特定の範囲(スコープ)内でしかアクセスできない変数となります。
以下のプログラムでは、7行目で宣言した変数「num02」が、11行目では参照できないため、コンパイルエラーとなってしまいます。
public class HensuMain {
public static void main(String[] args) {
int num01 = 100; // num01はmainメソッドの中だけ参照可能
if(num01 > 0) {
int num02 = 10; // num02はifブロック(※直前の{ }に囲まれた範囲)だけ参照可能
System.out.println(num01 + num02); // ここではnum01もnum02も使える
}
// ↓ ここではnum02は参照できないため、この行はコンパイルエラーになります
System.out.println(num01 + num02);
}
}
メンバ変数
Javaでは、変数はメソッドの外側にも宣言することが可能です。
以下のように、クラスの宣言の内側、かつメソッドの外側に宣言された変数を「メンバ変数」と呼びます。メンバ変数は同じクラスの中であれば、どの範囲でも参照することが可能です。
public class HensuMain {
private static int num03 = 10;
public static void main(String[] args) {
int num01 = 100;
if(num01 > 0) {
System.out.println(num01 + num03); // num01もnum03も参照可能
}
System.out.println(num01 + num03); // num03はここでも参照可能
}
}
変数のデータ型
前述したとおり、変数には様々な値を格納できますが、Javaでは変数にどのような値を格納するのか、変数の型(データ型)を変数を宣言する際に指定します。
下記の例では、変数「num01」「num02」はint型(整数)であることを宣言しています。
public class HensuMain {
public static void main(String[] args) {
int num01 = 100; // int型の宣言
int num02 = 100; // int型の宣言
System.out.println(num01 + num02); // 「200」と出力
}
}
Javaではデータ型は「プリミティブ型」と「参照型」に分かれます。
引き続き、これらのデータ型の内容について説明します。
プリミティブ型
プリミティブ型は「値型」とも呼ばれ、値を必ず持つ変数になります。
これらの変数は null になることがありません(Javaでは、null は「参照先を持たない」の意味)
Javaのプリミティブ型は、「真偽値」「数値」「文字(1文字のみ)」が格納可能で、以下の8種類が準備されています。
型 | 説明 | 初期値 | 最小値 ~ 最大値 |
boolean | 真偽値(true/false) | false | - |
byte | 整数 | 0 | -128 ~ 127 |
short | 整数 | 0 | -32,768 ~ 32,767 |
int | 整数 | 0 | -2,147,483,648 ~ 2,147,483,647 |
long | 整数 | 0 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 |
float | 単精度浮動小数点数 | 0 | -3.4028235E+38 ~ 3.4028235E+38 ※有効桁数は最大6桁 |
double | 倍精度浮動小数点数 | 0 | -1.79769313486231570E+308 ~ 1.79769313486231570E+308 ※有効桁数は最大14桁 |
char | unicode文字 | u0000 | u0000 (0) ~ uffff (65535) |
数値については、用途に応じて格納できる範囲が異なるデータ型が準備されていますが、ここでは下記の各型の説明の詳細や、最小値、最大値などは暗記しなくても問題ありません。(こういった種類があることは覚えておいてください)
プリミティブ型とリテラル値
プリミティブ型に値を設定する場合は「=」の右側に設定したい値を記述しますが、このとき設定する値を「false」「1」など値を直接記述する場合と、別の変数や、値を返すメソッドを記述する場合があります。
boolean b = false; // 設定する値を直接記述して指定(false)
int i = 1; // 設定する値を直接記述して指定(1)
int x = i; // 別の変数を指定(i)
このとき、「false」や「1」など、プログラムのコード上に「直接記述された値」のことを、「リテラル値」(または単に「リテラル」)と呼びます。
Javaでは、boolean型はfalse・trueの2つ、各数値の型は範囲内の値、char型は各unicode文字をリテラル値として記述することが可能です。
boolean型
boolean型は「true(トゥルー)」と「false(フォルス・フォールス)」のみ格納できるデータ型です。
trueは真であることを示す値で、falseはその逆(真でない)を示します。
プログラム上でなんらかの判定処理を行った結果など、正しいか(真であるか)どうかを格納しておく場合などに利用します。
byte型
byte型は1バイトのデータ量の整数値を格納できるデータ型です。
1バイトとは8ビット(2進数で8桁)のことで、byte型では8ビットで表現できる範囲の整数値(-128 ~ 127)を格納しておくことができます。
javaのプログラム上では整数の値を扱う場合は、一般的にint型またはlong型を利用することが多く、あまり目にする機会はないかもしれませんが、プログラム内部の制御などで利用することもありますので、「byte=1バイトのデータ」と覚えておいてください。
(値の範囲がどのように決まるのか興味がある方は、下記の「整数型の値の範囲はどのように計算される?」を読んでみてください)
※整数型の値の範囲はどのように計算される?
前述のとおり、1バイト=8ビットとなりますので、byteに格納できる値は「8桁の2進数」で表現できる範囲となります。
2進数で8桁ですので、そのまま考えれば「00000000」(10進数で0)~「11111111」(10進数で255)となりそうですが、Javaの数値の型は先頭の1桁が「プラスマイナスの符号」として扱われます。(0はプラス、1はマイナス)
このため表現できる範囲が以下のように決定されます。
正の値:「00000000」(0)~「01111111」(127)
負の値:「11111111」(-1)~「10000000」(-128)
Javaではshort、int、longの整数型では同じく先頭の1ビットが符号を示しますので、「nビットのデータ型」が表現できる数値の範囲は、いずれの場合も以下のとおり計算できます。
正の値: 0 ~ 2^(n-1) - 1 (2のn-1乗マイナス1)
負の値:-1 ~ -2^(n-1) (-2のn-1乗)
short型
short型は2バイトのデータ量の整数値を格納できるデータ型です。
2バイト=16ビットで表現できる範囲の整数値(-32,768 ~ 32,767)を格納しておくことができます。
前述のとおりint、longに比べ目にする機会は少ないと思いますが、機器制御などの理由で明示的に値の範囲を指定する必要がある場合などに利用されることがあります。
int型
int型は4バイトのデータ量の整数値を格納できるデータ型です。
4バイト=32ビットで表現できる範囲の整数値(-2,147,483,648 ~ 2,147,483,647)を格納しておくことができます。
処理した回数を数えたりするような一時的な数値を扱う場合や、簡単な数値の計算では主にこのint型が利用されます。
最大値が21億程度であるため、これより大きな数値が想定されるデータを扱う場合は、intではなくlongなど別の型が利用されることが多いです。
long型
long型は8バイトのデータ量の整数値を格納できるデータ型です。
8バイト=64ビットで表現できる範囲の整数値
(-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807)を格納しておくことができます。
最大値が922京程度まで格納できますので、世界の人口などの大きな整数値を扱う場合は、このlong型を利用することでほぼ対応できます。
(long型の範囲より大きな値は、格納できるプリミティブ型が準備されていないため参照型のデータとして扱うことになります)
long型の値をリテラル値として記述したい場合は、「l(または L)」を数値の後ろに記述します。
long l01 = 123456789012345l; // l を後ろにつける
long l02 = 1L; // L を後ろにつける
float型
float型は4バイトのデータ量の単精度浮動小数点数を格納できるデータ型です。
※単精度浮動小数点数とは?
float型の「単精度浮動小数点数」とdouble型の「倍精度浮動小数点数」は、米国電気電子学会が定める「IEEE754」というコンピューターに関する規格に定められた値の保持方法です。符号と基数(小数点の位置の表現)と2進数の整数の組み合わせで、幅広い小数の値を扱えるようになっています。
それぞれ32ビットと64ビットの2進数で小数を表すための規格となっていますが、2進数での制御となるため、float同士やdouble同士の計算で所定の精度を超えてしまう場合などに計算結果に誤差が生じる場合があるため、金利など厳密な計算が必要な小数を扱う場合は、これら以外の参照型の数値型変数を利用する必要があります。
最小値・最大値は-3.4028235E+38(-3.4028235 × 10^38)~ 3.4028235E+38(3.4028235 × 10^38)、最も小さな単位の小数としては1.401298E-45(1.401298 × 10^-45)を表現することが可能ですが、Javaでの有効最大桁数は6桁となっています。
float型の値をリテラル値として記述したい場合は、「f(または F)」を数値の後ろに記述します。
float f01 = 0.001f; // f を後ろにつける
float f02 = 1.234F; // F を後ろにつける
double型
double型は8バイトのデータ量の倍精度浮動小数点数を格納できるデータ型です。
最小値・最大値は-1.79769313486231570E+308(-1.79769313486231570 × 10^308)~ 1.79769313486231570E+308(1.79769313486231570 × 10^308)、最も小さな単位の小数としては4.94065645841246544E-324(4.94065645841246544 × 10^-324)を表現することが可能ですが、Javaでの有効最大桁数は14桁となっています。
double型の値をリテラル値として記述したい場合は、「d(または D)」を数値の後ろに記述します。
double d01 = 0.0000001d; // d を後ろにつける
double d02 = 1.2345678D; // D を後ろにつける
char型
charは2バイト(=16ビット)で表現される、1つだけの「文字」に対応する値を保持することができるデータ型です。
unicord文字は、世界中の文字に対して1つずつ16ビットの値(コード値)が定められているもので、この「1つの文字に対して割り当てられた値」を格納することで、対応する文字を判断することができるようになっています。
(文字に割り当てられた値を「コードポイント」と呼びます)
char型の変数に値を文字で設定する場合は、「'」(シングルクォーテーション)で囲います。
public class CharMain {
public static void main(String[] args) {
char a = 12354; // 「あ」に対応するコード値(10進数)
System.out.println(a); // 「あ」と出力される
char i = '井'; // 16進数: 4e95 ・ 10進数 20117
char u = 'う'; // 16進数: 3046 ・ 10進数 12358
char x = 'x'; // 16進数: 0078 ・ 10進数 120
// コード値なので計算もできる
System.out.println(u + x); // 12358 + 120 = 12478
}
}
参照型
インスタンス参照
参照型の変数には、Javaのクラスのインスタンスへの参照を保持します。
(インスタンスはクラスをオブジェクトとして実体化したものです。インスタンスの詳細についてはこの後説明します)
参照型の変数では、インスタンスの格納を行わない場合に「null」を設定することができます。
(nullを設定した場合、変数は名前だけ定義され、インスタンスとの紐づけがない状態になります)
String s1 = "こんにちは"; // 文字列「こんにちは」を持つStringクラスのインスタンスを格納
String s2 = null; // 変数s2にはStringクラスのインスタンスは格納されていない。
配列
Javaの配列は、同一の型のデータを複数個まとめて管理しておくことができます。変数を宣言するときに、格納したい型の後ろまたは変数名の後ろに [ ] を追加することで、配列として宣言することができます。(両方につけることも可能ですが、一般的にはどちらか一つだけに追加します)
int[] intArray01 = {0,1,2,3}; // 型の後ろに[]
int intArray02[] = {4,5,6,7,8,9}; // 変数名の後ろに[]
配列に格納したデータは順番(0番目、1番目、2番目~)で管理されるので、任意の場所にデータを出し入れすることができます。
(同じ型のデータだけがおさまる、小分けの箱をイメージしてもらうとわかりやすいかもしれません)
intArray01[1] = 10; // 変数intArrayの1番目に10の値を設定する
int i = intArray02[2]; // 変数 i の値にintArray02の2番目の値(6)を設定する
配列は作成時に要素の数(配列のサイズ)が決まるため、この範囲外の位置に値を設定や取得を行おうとすると実行時にエラーになります。
intArray01[4] = 10; // intArray01は0~3番目までしかないのでエラーになる
intArray02[-1] = 0; // 不正な位置(負の値)を指定しているためエラーになる
配列ではプリミティブ型の配列、参照型の配列どちらでも宣言できますが、たとえプリミティブ型の配列であっても、宣言された変数は参照型になります。
下の例では、プリミティブ型、参照型両方の配列に、nullを設定しています。
int[] intArray = {2,3,5,7,11,13,17,19};
String[] strArray = {"こんにちは", "hello", "你好", "buon giorno"};
intArray = null; // プリミティブ型の配列でもnullを設定可能
strArray = null; // 参照型の配列ももちろんnullを設定可能
配列自体が参照型になるので、配列の配列(多次元配列)も作成可能です。2層以上の配列にする場合は、[ ] を階層の数だけ続けて記述します。
例) int[ ][ ] ← 「intの配列(int[ ])」の配列 になります
この場合は「参照型の配列」になるので、要素にnullが指定できることや、各要素が同じ型の配列であれば要素の数(サイズ)が違っても格納できることに注意してください。
int[][] multiArray = {{0,1,2}, {3,4,5,6}, null, {7,8,9}};
System.out.println(multiArray[1][0]); // 1番目の0番目 ⇒ 「3」が出力される
変数名と予約語
変数名のルール
Javaの変数名には以下のようなルールがあります。
・記号は「 _ 」(アンダースコア)と「$」(ドルマーク)のみ利用できる。
(ただし、アンダースコア1文字だけの変数名は利用できない)
・数字は利用できるが、変数名の先頭には利用できない。
・大文字と小文字は区別される。
・予約語として定められた文字列と同じ変数名は利用できない。
(予約語については後述します)
・「null」は変数名に利用できない。
// _ と $ は利用可能
int a_ = 0;
int a$ = 0;
int $ = 0; // $は1文字だけでも利用可能
// 数字は利用可能(先頭以外)
int a1 = 0;
// 大文字と小文字は区別される
int abc = 0;
int aBc = 0; // Bが大文字なので別とみなされる
//★以下は利用できない例★//
int 1a = 0; // 先頭が数字
int 1a = 0; // 全角数字でも同様
int a@1 = 0; // _ と $ 以外の記号
int new = 0; // 予約語(new)と同じ
int null = 0; // 「null」は変数名に利用不可
変数名のつけ方と注意点
変数名のつけ方はプロジェクトチームや組織などによって定められていることが多いですが、ここではいくつかの一般的なポイントについて述べます。
(1)変数名の先頭の文字
通常、Javaではクラス名は先頭を大文字で始めるため、これと区別するため変数名の先頭は小文字のアルファベットを利用することが一般的です。
定数(として利用する変数)などを宣言する場合を除き、大文字アルファベットから始まる変数名を利用するのは避けましょう。
(2)いくつかの単語を持つ場合
大きなプログラムを作成している場合などでは、変数名からも意味が判別しやすいような変数名を設定することが一般的です。
特に、変数名を複数の単語から構成する場合などは、いくつかの表記方法があります。また、複数単語で構成する場合は「number」を「num」と省略するなど、変数名が長くなり過ぎないようにします。
ここでは、一般的に変数名に利用される記法を示します。
・キャメルケース(キャメル方式)
2番目以降の単語の先頭を大文字にすることで、単語の区切りを示す記法です。
Javaの変数名、クラス名では一般的な記法となっています。
例)旅行者数「number of tourists」→ numberOfTourists、numOfTourists
・スネークケース
単語の間をアンダースコアでつなぐことで、単語の区切りを示す記法です。
プログラム言語によっては、こちらが一般的な変数名のつけ方の場合もあります。
例)旅行者数「number of tourists」→ number_of_tourists
(3)避けるべき変数名
以下のような変数名は設定することは可能ですが、利用は避けたほうが良いでしょう。
・型を誤認するようなもの
例: 「int stringValue」「String number」
・予約語と同じような名前
例:「int whiles」「String Null」
・長すぎるもの、意味が不明なもの
例:「int secoundsInTermsFrom2000Jan01To2024Dec31」「int agathaaaagabrnn」
ちなみに変数名にはアルファベット以外の文字(ひらがな、漢字など)も利用することができますが、環境によっては文字化けしてしまう場合がありますので推奨しません。
(アンダースコアとドルマーク以外の記号については、全角であっても利用できません)
また、日本語を利用できる環境では、以下のような全角文字の混入にも注意しましょう。
String hello = "こんにちは"; // 「h」だけ全角
予約語とは?
Javaでは特定の用途が決められた単語を予約語として定められています。
予約語に定められている単語は、変数、クラスなどの名前(識別子)として、そのまま使用することはできません。
Javaの変数名は大文字と小文字が区別されるため、先頭を大文字にした場合などは予期せず設定できてしまうため、注意してください。
予約語の一覧
Javaでは以下の51個の予約語が定義されています。
予約語は主に型の名前や、Javaが準備している制御用の単語などが登録されています。
・abstract
・catch
・do
・finally
・import
・new
・short
・this
・volatile
・assert
・char
・double
・float
・instanceof
・package
・static
・throw
・while
・boolean
・class
・else
・for
・int
・private
・strictfp
・throws
・_
(アンダースコア)
・break
・const
・enum
・goto
・interface
・protected
・super
・transient
・byte
・continue
・extends
・if
・long
・public
・switch
・try
・case
・default
・final
・implements
・native
・return
・synchrnized
・void
変数の型推論(Java 10以降のバージョン)
Java 10以降のバージョンでは、メソッド内のローカル変数に限り、型のかわりに「var」キーワードを記述することで、変数の型を指定しなくても宣言できるようになりました。
varキーワードで変数を宣言する場合は、宣言と同時に値を指定(初期化)する必要があります。これは、varキーワードで宣言していたとしても、宣言と同時に変数の型を初期値から決定するためです。
この、設定した値によって変数の型が自動的に決定されることを「型推論」と言います。
var vnum = 0; // 宣言時に設定した値(0)から、整数値のデフォルトであるint型の変数になる
var vfloat = 0f; // 設定した値(0f)から、float型の変数になる
上記のとおり、varキーワードを利用しても宣言と同時に変数の型が決まるので、後から違う型の値を設定することはできません。
また、varキーワードでは配列の変数の宣言はできません。
var vchar = '1';
var vstr = "Hello";
// 型が違うため、以下のような代入はできない(コンパイルエラーになる)
vstr = vchar; // 型に互換性がない(Stringとchar)
vstr = 0; // 型に互換性がない(Stringとint)
// 配列の宣言もできない(コンパイルエラーになる)
var varray = {0, 1, 2};