Java Silver🥈の試験対策として、Javaのプリミティブ型についてまとめました。
- 🛑間違いやすい! 見直しポイント
- ⭐とりあえずこれだけでも! 重要ポイント
- 👁🗨着眼点・理由
- 📖用語
リテラル
ソースコードに直接記載される値のこと
整数リテラル
ソースコードに直接記載される数値を表す数字
2・8・16進法表記
|
2進法 |
8進法 |
10進法 |
16進法 |
先頭の文字 |
0b |
0 |
(なし) |
0x |
例 |
0b1010 |
0777 |
42 |
0xCAFE |
- 🛑先頭に
0
をつけると8進法になる
-
0999
などはコンパイルエラー
- うっかり先頭を
0
でパディングしないように注意!
区切り文字"_
"
// 使用例)Byteごとに区切って分かりやすくする
int mask = 0x00_00_FF_FF;
int hogeFlagBit = 0b00000000_00000000_00001000_00000000;
int a = _1234 // ✘
int b = 1234_ // ✘
int c = 0x_ABCD // ✘
-
_
は整数リテラルのみ有効
- 🛑
Integer.parseInt
は_
を受け付けない(NumberFormatException)
ブール値リテラル
- ソースコードに直接記載されるブール値を表すキーワード
文字リテラル
- ソースコードに直接記載される文字型を表す句
- ⭐シングルクォーテーション(
'
)で文字を囲う
- 🛑文字リテラルは整数型に代入可能
プリミティブ型のサイズと大きさ
- プリミティブ型はそれぞれで扱える値の範囲とメモリサイズのbit数が決まっている
型 |
bit数 |
最小値 |
最大値 |
byte |
8 |
⭐$-2^7 = -128$ |
⭐$2^7-1 = 127$ |
short |
16 |
⭐$-2^{15} = -32768$ |
⭐$2^{15}-1 = 32767$ |
int |
32 |
$-2^{31} = 2147483648$ |
$2^{31}-1 = 2147483647$ |
long |
64 |
$-2^{63}$ |
$2^{63}-1$ |
char |
🛑16 |
$0$ |
$2^{16}-1$ |
float |
32 |
$-(2 - 2^{-23} \cdot 2^{127})$ |
$2 - 2^{-23} \cdot 2^{127}$ |
double |
64 |
$-(2 - 2^{-52} \cdot 2^{1023})$ |
$2 - 2^{-52} \cdot 2^{1023}$ |
- 👁🗨浮動小数 (float, double) は符号・指数部・仮数部に分かれている
- 仮数部と2の指数乗の積が値になる
- 符号部で値の正負を決める
名称 |
float |
double |
符号部 |
1bit |
1bit |
指数部 |
8bit |
23bit |
仮数部 |
11bit |
52bit |
- 仮数部の長さによって浮動小数点の値の精度が決まる
- 整数を浮動小数で表現すると精度が落ちる
プリミティブ型の拡大変換
- ⭐プリミティブ型の変数を使用するとき、値域が小さい型から大きい型へと自動で変換してくれる機能
- 変換は値を使用するとき(以下の場合)に行われる
- 代入するとき
- メソッドの引数として渡すとき
- 演算するとき
- 拡大変換は扱える値の範囲が狭い型から広い型へと変換する場合にのみ行われる
-
short
➡long
やint
➡double
の変換は拡大変換になる
- 🛑
long
➡float
はbit数が64bitから32bitと減少するが拡大変換される
- 🛑
short
➡char
はbit数が同じだが互いに拡大変換されない
- ⭐拡大変換できない場合はキャストによる明示的な変換が必要
double d = 1.23d;
int i = (int) d; // キャストによる明示的な変換
👁🗨拡大変換の対応表
(✔:対応している ✘:対応していない(要キャスト))
変換元\変換先 |
char |
byte |
short |
int |
long |
float |
double |
char |
- |
✘ |
🛑✘ |
✔ |
✔ |
✔ |
✔ |
byte |
✘ |
- |
✔ |
✔ |
✔ |
✔ |
✔ |
short |
🛑✘ |
✘ |
- |
✔ |
✔ |
✔ |
✔ |
int |
✘ |
✘ |
✘ |
- |
✔ |
✔ |
✔ |
long |
✘ |
✘ |
✘ |
✘ |
- |
🛑✔ |
✔ |
float |
✘ |
✘ |
✘ |
✘ |
✘ |
- |
✔ |
double |
✘ |
✘ |
✘ |
✘ |
✘ |
✘ |
- |
ラッパークラス
- ラッパークラス:プリミティブ型をオブジェクト化し、参照型で扱えるようにしたもの
- オートボクシング:プリミティブ型⇔ラッパーの相互の自動変換機能
- ラッパークラスのインスタンスをあたかもプリミティブ型であるかのように使える
-
char
型のラッパークラスはCharacter
プリミティブ型 |
ラッパ型 |
ボクシング |
アンボクシング |
文字列から変換 |
byte |
java.lang.Byte |
valueOf(byte) |
byteValue() |
parseByte(String) |
short |
java.lang.Short |
valueOf(short) |
shortValue() |
parseShort(String) |
int |
java.lang.Integer |
valueOf(int) |
intValue() |
parseInt(String) |
long |
java.lang.Long |
valueOf(long) |
longValue() |
parseLong(String) |
float |
java.lang.Float |
valueOf(float) |
floatValue() |
parseFloat(String) |
double |
java.lang.Double |
valueOf(double) |
doubleValue() |
parseDouble(String) |
boolean |
java.lang.Boolean |
valueOf(boolean) |
booleanValue() |
parseBoolean(String) |
char |
🛑java.lang.Character |
valueOf(char) |
🛑charValue()
|
🛑 (なし1) |
オートボクシング
- ラッパークラスのインスタンスは、プリミティブ型と演算するとき自動的にプリミティブ型に変換される
void test(){
Integer integer = Integer().intValue(123);
int i = integer.intValue();
// プリミティブ型とラッパクラス型の論理演算
// Integer型がint型に自動変換される
boolean b = (i == integer);
}
var
型
- 変数の型を指定しなくても自動で推定してくれる機能
- ⭐
var
はローカル変数専用
- ⭐
var
の初期化は必須
- 🛑
var
はnull
では初期化できない(型を推定できないため)
class Test {
// ✘varはフィールドでは使えない(コンパイルエラーになる)
var variable;
void test() {
// ✓右辺がint型なのでvarはint型と推定される
var varIntegerA = 0;
// ✘varは宣言時に初期化もしないといけない(コンパイルエラーになる)
var varIntegerB;
varIntegerB = 1;
// ✓varで拡張for文の変数の型を推定させることもできる
java.util.List<String> list = Arrays.asList("A", "B", "C");
for (var str : list) { // listの要素はString型なのでvarはString型と推定される
System.out.println(str);
}
}
}
演算子
-
演算子:計算を意味する記号
-
単項演算子:
++
など、1つの値を取る演算子
-
二項演算子:
+
, *
など、2つの値を取る演算子
-
三項演算子:
?
など、3つの値を取る演算子
-
オペランド:演算子で計算する対象の値
演算子の結合の強さ
- 演算子には結合の強さが決められている
- 算数でいえば式で出てくる順番にかかわらず、+より×を先に計算するのと同じ考え方
- プログラムは演算子の結合が強い方から順に計算される
- 重要な結合の強さを覚えておこう(
()
内の式が先に計算される)
-
1 + 2 * 3
➡ 1 + (2 * 3)
-
a || b && c
➡ a || (b && c)
-
!a && b
➡ (!a) && b
-
1 + ++i
➡ 1 + (++i)
- 🛑
(int) 1.2 + 3.4
➡ ((int) 1.2) + 3.4
- 小数の計算結果を整数に変えたいときは
(int) (1.2 + 3.4)
とする
- 🛑
flag ? 3 : 1 * n
➡ flag ? 3 : (1 * n)
-
n
の値をflag
がtrue
のときだけ3
倍にしたいときは(flag ? 3 : 1) * n
とする
演算子の結合強さ表
- 表の上の方に行くほど結合が強くなる
- 演算子の記号
-
T
:型
-
I
:識別子
-
X
:値(オブジェクト含む)
-
N
:数値
-
B
:論理値
演算子 |
内容 |
I() I[] I.I new T N++ N--
|
func("A") array[0] obj.value new String("ABC") i++ i--
|
!B ~N +N -N ++N --N
|
!isFoo ~mask +12.3 -273.15 ++i --i
|
(T) |
(int) 12.3 |
N*N N/N N%N
|
2*3 |
N+N N-N
|
1+1 |
N<<N N>>N N>>>N
|
シフト演算 |
N>N N>=N N<N N<=N instanceof
|
論理比較 |
X==X X!=X
|
X == 42 |
X&X |
ビット演算のAND |
X^X |
ビット演算のXOR |
X\X |
ビット演算のOR |
B&&B |
論理演算のAND |
B||B |
論理演算のOR |
B?X:X |
(x >= 0)? x : -x |
I=X I+=N I-=N I*=N I/=N I%=N I<<=N I>>=N I>>>=N I&=N I|=N I^=N
|
演算と代入 |
インクリメント演算子
-
++
・--
の演算子で整数型の変数の値を1増やす・1減らすことができる
- メモリを読む、値を増やす、メモリに書き込む(副作用)という3つの動作がある点に注意
-
++
を変数につける場所で動作が変わる
- 左に着けると評価 → インクリメントの順に処理される
- 右につけるとインクリメント → 評価の順に処理される
int a = 0;
System.out.println(a++); // "0"
System.out.println(a); // "1"
int b = 0;
System.out.println(++b); // "1"
System.out.println(b); // "1"
- 演算は基本的に左から実行される
-
n + n++ + --n
は((n + n++) + --n)
と考える。
int n = 10;
int a = n + n++ + --n; // 30になる
🛑String連結演算子 +
-
String
クラスは特別に+
演算子が用意されている
- ふたつの文字列をひとつの文字列に連結して返す
- オペランドの片方が
String
型ならString
の+
演算子の扱いになる
-
String
以外のオペランドはtoString
で文字列化される
- 🛑
0 + "1"
は"01"
になる(左側がString
以外でも変換される)
- ⭐値の
+
演算子と混ざっているときは特に注意!
// 2つの+演算子が混ざっている例
// (3 + 4).concat("7").concat("5").concat("2");
System.out.println(3 + 4 + "7" + 5 + 2); // 7752
2023/08/05 拡大変換の内容を追記・修正(PECMMさん、指摘ありがとうございます!)
2023/10/08 演算子の表の誤りを修正(PECMMさん、指摘ありがとうございます!)、表があるとそれを全部覚えないといけないのかという感じがするので折り畳み表示に変更し重要点だけ文章に抜出、その他字句修正