この記事では、当社 の新人エンジニア研修の参考にJava8を解説します。
前回は変数とデータ型について解説しました。
今回は演算子を解説します。
Javaには様々な演算子がありますが、ここではその中でも
・算術演算子
・キャスト演算子
を解説します。
・比較演算子
・条件演算子
・三項演算子
については、次回の4.条件分岐と判定条件でお話しします。
1.算術演算子
Javaで足し算をしてみましょう。
1 2 3 4 5 6 7 8 |
package chap03; public class Example01 { public static void main(String[] args) { System.out.println(1 + 2); } } |
このブログラムを実行すると標準出力には「3」と出力されます。
この時の、「+」記号を演算子(オペレータ)と呼び、2や3のことをオペランドと呼びます。
また、「1 + 2」 は3という値を持つため式と呼ばれます。
さらに、 System.out.println(1 + 2);のように;(セミコロン)までを文というのでしたね。
演算子自体はいろいろな使い方をしますが、+記号は足し算を意味するので特に算術演算子といいます。
ここで、Javaの算術演算子をまとめましょう。
算術演算子 | 演算内容 | 式の例 | 結果(値) |
+ | 足し算 | 1 + 2 | 3 |
– | 引き算 | 1 – 2 | -1 |
* | 掛け算 | 2 * 3 | 6 |
/ | 割り算 | 5 / 2 | 2 ※ |
% | 剰余(余りを求める) | 5 % 2 | 1 |
※ここで、5 / 2 = 2.5 ではなく、2となることに注目してください。整数同士の演算では結果も整数になるからです。小数点以下は切り捨てられるわけです。
また、数学でも掛け算と割り算(そして剰余)は、足し算と引き算より優先され先に計算されました。Javaでも同じです。
そのため
System.out.println(1 + 5 % 2);
の結果は、2になります。
()を使って以下のように優先順位を変更してみましょう。
System.out.println((1 + 5) % 2);
上記の結果は、0になります。
2.変数を含む式
式には変数を含めることもできます。
以下のプログラムは2から順に5まで1つづ増やした数を表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package chap03; public class Example02 { public static void main(String[] args) { int i = 1; int j = i + 1; System.out.println(j); j = j + 1; System.out.println(j); System.out.println(j += 1); //短縮表記の例1 System.out.println(++j); //短縮表記の例2 System.out.println(j++); //短縮表記の例2 System.out.println(j); } } |
<結果>
2 3 4 5 5 6 |
間違えやすいので繰り返しですが、上記の
int j = i + 1;
という式は数学の左辺と右辺が等しいという意味ではありません。
変数jにi+1という式の値を代入するという意味です。
=は代入を意味するということは後々まで間違えやすいところなので気をつけましょう。
また、上記のように変数を使った式は短縮表記も可能です。
j += 1
複合代入演算子といいます。
複合代入演算の作り方は以下の通りです。

複合代入演算子の書き方
以下に加算以外の例を示します。
number -= 2; number *= 2; number /= 2; number %= 2; |
変数名が長くなれば短縮効果が効いてくる書き方です。
また、短縮表記の例2のような書き方で1増やす処理をインクリメントといいます。
1減らすデクリメントというものもあります。(例:–j)
インクリメント、デクリメントにはオペランドに対してどこに書かれるかによって前置と後置があります。
前置は、式の中でオペランドの値は増やされたり減らされたりした“後”の値が用いられます。
後置は、式の中でオペランドの値は増やされたり減らされたりする“前”の値が用いられます。
例えば、上記の短縮表記の例2において
System.out.println(j++); //表示結果は5のまま
System.out.println(j); //1インクリメントされた6が表示される
ということになります。
なお、
i++;
++i;
のように単独で使った場合は前置、後置は同じ結果になります。
3.変数の型と代入の制限
前回、変数には型があって入れられる数値の範囲が違うということを学びました。
では、例えばdouble型の変数にint型の整数を入れるとどうなるでしょうか?
また、その逆はどうでしょうか?
やってみましょう。
1 2 3 4 5 6 7 8 9 |
package chap03; public class Example03 { public static void main(String[] args) { double d = 1; System.out.println(d); } } |
<結果>
1.0 |
エラーにはなりませんでした。
これを暗黙的な型変換といいます。
「大は小を兼ねる」ということでより大きな型への代入は暗黙の型変換がされます。
しかし、以下のようなプログラムはエラーになります。
1 2 3 4 5 6 7 8 9 |
package chap03; public class Example04 { public static void main(String[] args) { int i = 3.14; System.out.println(i); } } |
<結果>
(中略)- 不適合な型: 精度が失われる可能性があるdoubleからintへの変換 |
このように精度が失われる可能性のある代入はできません。
しかし、もし、プログラマーが精度が失われても構わないと考えた場合にも代入できないとすると不都合です。
それを可能にするのがキャスト(cast)演算子です。
4.キャスト演算
キャスト演算は()カッコを使います。
1 2 3 4 5 6 7 8 9 |
package chap03; public class Example05 { public static void main(String[] args) { int i = (int) 3.14; System.out.println(i); } } |
今回は3と表示されました。
このような演算をキャスト演算または型変換と呼びます。
よく、映画などで俳優のキャスティング(英:casting)という言い方をします。
悪役にキャスティングされた俳優は悪役としてふるまい、ヒーローにキャスティングされたらヒーローとしてふるまう。
違った型としてふるまうように指定するのがこのキャスト演算です。
あとでオブジェクトのキャストという応用のお話も出てきますので、しっかり押さえてください。
では、例えば、異なる型の変数や値が混在している演算の結果はどうなるでしょうか?
答えは、最も大きい型に統一された計算結果になります。
1 2 3 4 5 6 7 8 9 10 |
package chap03; public class Example06 { public static void main(String[] args) { int i = 1; double d = 3.1; System.out.println(i + d); } } |
<結果>
4.1 |
intとdoubleの算術演算はdouble型の結果になりました。
ここで気を付けたいのは整数同士の割り算です。
System.out.println(5 / 2);
int同士の割り算の結果は「2」になりました。
もしも、2.5と表示させたいのであれば、どちらかのオペランドをdoubleにキャストする必要があります。
例えばこんな風に、
System.out.println(5 / (double)2);
です。
5.ArithmeticException
また、以下のように割る数を0にしたらどうなるでしょうか?
1 2 3 4 5 6 7 8 |
package chap03; public class Example07 { public static void main(String[] args) { System.out.println(5 / 0); } } |
<結果>
ArithmeticException: / by zero |
とエラーが表示されます。
もちろん、意図的にこのような計算をすることはないでしょう。
しかし、割る数が変数ですと意図せず0で割ってしまうこともあります。
そんな時は、「もしも、割る数が0だったら処理をしない」といった条件分岐や、
エラーが発生しても処理を止めない例外処理といったことが必要になります。
この点は後述しますね。
6.文字列の結合に使用する「+」
文字列はString型の変数に代入できます。
1 2 3 4 5 6 7 8 9 |
package chap03; public class Example08 { public static void main(String[] args) { String str = "Hello World"; System.out.println(str); } } |
※文字列は別の章で詳しく学びます。
また、文字列を連結するには「+」演算子を使います。
1 2 3 4 5 6 7 8 9 10 |
package chap03; public class Example09 { public static void main(String[] args) { String str1 = "Hello"; String str2 = " World"; System.out.println(str1 + str2); } } |
<結果>
Hello World |
しかし、「+」演算子は足し算でも使いましたね。
文字列と数値が混在する場合はどうなるでしょうか?
1 2 3 4 5 6 7 8 9 |
package chap03; public class Example10 { public static void main(String[] args) { System.out.println("1 + 2 = " + 1 + 2); System.out.println(1 + 2 + " is the answer to 1 + 2"); } } |
結果
1 + 2 = 12 3 is the answer to 1 + 2 |
算術演算子には左結合というルールがあります。
左から順番に評価されるというルールです。
そのため、文字列に連結された時点で全体が文字列と評価されるので上記の結果になるのです。
更に応用的な知識として文字列を+で結合することはパフォーマンスが悪いことにも注意しましょう。
7.文字と文字列の扱いで詳しくお話ししますが、ここでも簡単に触れておくと
文字列は1度生成すると内部の文字列を変更できません。
数回の結合であれば問題になりませんが、何千何万回となると影響があります。
そのような場合にはStringBuilderクラスまたは、StringBufferクラスのappendメソッドの使用を推奨します。
ここまで理解できたら、まとめとして演習問題にチャレンジしましょう。
今回はJavaの演算子について見てきました。
次回は、条件分岐と判定条件を学んでプログラムに様々な判断をさせてみましょう。
JavaSE8の解説に戻る