Javaの演算子の基本
Javaの演算子には、次のようなものがあります。
- 算術演算子:
+
,-
,*
,/
,%
は基本的な算術演算子です。除算演算子/
に注意が必要で、整数(int型)の除算では商の整数部分のみが結果として得られます。 - 単項演算子:
+
,-
,++
,--
,!
などは単項演算子です。++
および--
は変数を1増減させるために使用され、前置と後置の2つの形式があります。これらは結果が異なるため注意が必要です。 - 代入演算子:
=
,+=
,-=
,*=
,/=
,%=
は変数に値を代入するための演算子です。
ビット演算子として&=
,|=
,^=
,<<=
,>>=
,>>>=
がありますが、Silverではあまり出題されてないようです。 - 比較演算子:
==
,!=
,<
,>
,<=
,>=
は比較のために使用されます。オブジェクトを比較する場合、==
は参照の同一性を比較し、equals()
メソッドを使用して内容を比較することが推奨されます。 - 論理演算子:
&&
,||
,!
は論理AND、論理OR、論理NOTを表します。&&
および||
は短絡評価を行います。これは、結果が既に決定されている場合、残りの式は評価されないことを意味します。 - ビット演算子:
&
,|
,^
,~
,<<
,>>
,>>>
はビット単位の操作に使用されます。これらは通常、低レベルなプログラミングやパフォーマンスが重要な場面で使用されます。 - 三項演算子:
? :
は三項演算子であり、条件式を短く書くことができます。
例:int result = (a > b) ? a : b;
- instanceof演算子:
instanceof
はオブジェクトが特定のクラスまたはインターフェースのインスタンスであるかどうかをチェックするために使用されます。 - キャスト演算子: Javaでは、型間の変換を行うためにキャスト演算子
(type)
を使用します。キャストは暗黙的または明示的に行うことができますが、データの損失を防ぐために注意が必要です。
これらの演算子を使用する際は、優先順位と結合規則に注意し、必要に応じて括弧を使用して式をグループ化するとよいでしょう。また、コードの可読性を保つために、演算子を適切に使用することが重要です。
ビット演算子はSilverではあまり重要視されてないようですが、概念は知っておくべきです。
Silver対策:演算子のポイント
次のコードを読んで、意味が判らない場合は、Eclipseなどのデバッグモードを使ってステップオーバーで確認してみると良いです。
次のコードの結果を11になると間違わないように。
int a = 3;
int b = a += 5;
System.out.println(a + b); //正解は16
マイナス演算子には減算のための2項演算子と正負を入れ替える単行演算子があります。
int num = 10;
System.out.println(10 * -num); // -100
インクリメント・デクリメント
ソースコード内で1を足す場合「++」インクリメント、1引く場合は「—」デクリメントを使用します。これらには、前置と後ろ置きがあり動作が異なりますので注意が必要です。
インクリメント、デクリメント後に計算結果を代入するような用途では挙動が変わりますので注意が必要です。
前置
計算してから代入します。
int a = 10;
int b = ++a; //11
int a = 10;
int b = ++a + 10; //21
後ろ置き
代入後に計算します。これは間違いやすいので何度も練習しましょう。
int a = 10;
int b = a++;
最終的に、bは10、aは20になります。
次の場合が間違いやすいので注意
int a = 10;
int b = a++ + 10;
最終的に、bは20、aも20になります。
試してみよう
次のコードは何と表示されますか。実際にコードを試すのではなく考えて下さい。答えがわかったら実際にコードで結果を確認してください。間違ったら何度も同様の計算練習をしましょう。Silver対策
public class Main3 {
public static void main(String[] args) {
int a = 10;
int b = a++;
System.out.println(b++ + a++ - --a);
}
}
数値の型変換のポイント
- データ損失: キャストすると、情報が失われる可能性があります。例えば、
float
をint
にキャストすると、小数部分が切り捨てられます。 - オーバーフローとアンダーフロー: キャスト先の型の範囲が小さい場合、オーバーフローまたはアンダーフローが起こる可能性があります。例えば、大きな
int
をbyte
にキャストすると、値が循環します。(127以上だとbyte範囲-128から127の値のどれかが順番に出てきます)コンパイルエラーでは無いことに注意 Silver対策 - 浮動小数点から整数へのキャスト: 浮動小数点数を整数にキャストすると、小数部分が切り捨てられます。四捨五入をしたい場合は、
Math.round()
メソッドを使用してください。Math.round()
はlong型を返します。 - 符号拡張:
byte
やshort
をint
やlong
にキャストする際、符号拡張が行われます。これは、最上位ビット(符号ビット)が拡張されることを意味します。このため、無符号値として扱う場合は注意が必要です。 - 暗黙的なキャスト: キャストは時々暗黙的に行われます。たとえば、
int
をdouble
に代入するとき、Javaは自動的にint
をdouble
にキャストします。 - 明示的なキャスト: 範囲の広い型から範囲の狭い型へのキャストは、明示的に行う(()を使用)必要があります。これは、データの損失が発生する可能性があるためです。
- NaNと無限大の扱い: 浮動小数点数には特殊な値NaN(非数)や無限大が存在します。これらの値を整数にキャストすると、特定の整数値に変換されます(
NaN
は0
に、正の無限大はInteger.MAX_VALUE
に、負の無限大はInteger.MIN_VALUE
になります)。
double a = Double.NaN; のようにして使用します。 - 精度と範囲: 浮動小数点数の精度は限られており、非常に大きな整数値を
float
やdouble
にキャストすると、精度が損なわれることがあります。
数値のキャストを行う際は、これらのポイントを考慮して、データの損失や予期しない結果が発生しないように注意してください。また、コードの可読性と保守性を考慮し、キャストが必要な理由をコメントで説明することが推奨されます。
同一性と同値
Javaでは、==
演算子と equals()
メソッドは、オブジェクトの「同一性」および「同値性」を判定するために使用されます。これらの用語とそれぞれの使い方について説明します。
- 同一性:
- 同一性は、2つのオブジェクト参照が同じオブジェクトを指しているかどうかを判定します。
==
演算子は、オブジェクトの同一性を判定するために使用されます。- 例えば、
object1 == object2
は、object1
とobject2
がメモリ上で同じオブジェクトを指している場合にtrue
を返します。
- 同値性:
- 同値性は、2つのオブジェクトが論理的に等しい内容を持っているかどうかを判定します。
equals()
メソッドは、オブジェクトの同値性を判定するために使用されます。object1.equals(object2)
は、object1
とobject2
の内容が論理的に等しい場合にtrue
を返します。
ダブルクオテーション(””)で文字列を作成したらコンスタントプールが作成されるため同一性になります。そのため、 == で同じ文字列か比較することができます。明示的にコンスタントプールを作成したい場合はintern()を使用します。
参考例
public class Lesson3_1 {
public static void main(String[] args) {
String str1 = "abc";
String str2 = new String("abc");
String str3 = "abc";
System.out.println(str1 == str2); //同一性の比較
System.out.println(str1.equals(str2)); //同値の比較
System.out.println(str1 == str3); //コンスタントプール
System.out.println(str1.equals(str3));
System.out.println(str1.intern() == str2.intern());
}
}
if文構文
Javaのif
文はプログラミングの基本的な制御構造の一部です。以下はif
文を使用する際の重要なポイントです。
- 条件式の評価:
if
文の条件式はboolean
型である必要があります。つまり、結果がtrue
またはfalse
となる式でなければなりません。 - ブロックと単文:
if
文の中には単一の文または複数の文を含めることができます。単一の文の場合、波括弧{}
はオプションです。複数の文を含む場合は波括弧で囲む必要があります。
{}
を省略する場合はif文の範囲が分かりにくくなります。試験の際は一旦{}
をつけて考えると良いです。また、省略した場合は単一の文しか書けませんので引っかけ問題に注意するようにしましょう。 - elseブロック: 条件式が
false
の場合に実行されるelse
ブロックをオプションで追加することができます。 - else if構造: 複数の条件を順にチェックする場合、
else if
を使用して連鎖的な条件を作成することができます。 - 短絡評価: 論理演算子
&&
(AND)および||
(OR)は短絡評価を行います。つまり、&&
の左側がfalse
の場合、右側は評価されず、||
の左側がtrue
の場合、右側は評価されません。これは、パフォーマンスを向上させるだけでなく、副作用を防ぐのにも役立ちます。 - 三項演算子: 簡潔な
if-else
文は、三項演算子(? :
)を使用して1行で書くことができます。これは、条件式 ? trueの場合の値 : falseの場合の値 の形式で書かれます。 - nullチェック:
if
文を使用してオブジェクトがnull
でないことを確認することがよくあります。これはNullPointerException
を防ぐために重要です。
- if文で{}は省略できますが、条件の()は省略できません。また、thenやendifなどのキーワードはないです。Silver対策
- if文でelseなど指定しない場合、{}を省略した場合は文は1つだけ使えます。2行になった場合は、if文から抜けることになりますのでSilverの引っ掛け問題に注意してください。Silver対策
- elseが入った時も同様に{}は省略できます。この場合も省略すると1行しか文を書くことはできません。Silver対策
- else改行ifとした場合は、else ifではなく、elseの中にif文を書いたことになる。else文の中にif文を書くのは有り。
- else文やif else文はその前の条件でマッチした場合は、マッチした条件以降のものは実行されずに抜けます。
- {}を省略するとき、条件式の()の後にセミコロンはつけないので注意。
public class Lesson5 {
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ.
int num = 10;
if(num < 10)
System.out.println("A");
else
System.out.println("B");
if(num==10)
System.out.println("C");
}
}
// BC
switch文
switch(){
case 値:処理
break;
case 値:処理
break;
default:処理
break;
}
switch文の条件式が戻せる値の型には、char, byte, short, int, Character, Byte, Short integer, String, Enum型がある。つまりint型以下の整数型、文字と文字列、列挙型
Javaのswitch
文を使用する際には、いくつかのポイントに注意する必要があります。
- 型の制限: 上記で説明したように、
switch
文で使用できる型には制限があります。 - breakキーワード: 各
case
ブロックの最後には通常break
キーワードを使用します。これにより、そのcase
ブロックの実行が終了したらswitch
文を抜けます。break
を省略すると、次のcase
ブロックが実行される(fall-through)。 - defaultブロック:
switch
文内にdefault
ブロックを記述することができます。これは、どのcase
にも該当しない場合に実行されるブロックです。 - 定数式:
case
ラベルには定数式しか使用できません。これは、コンパイル時に値がわかっていなければなりません。 - switch式(Java 14以降): Java 14以降では、
switch
文を式として使うことができます。これをswitch
式といい、これによりswitch
文で値を返すことができます。switch
式では、ラムダ式のようなアロー(->
)を使って、各case
での戻り値を指定することができます。 - 重複しないケース: 各
case
ラベルの値は一意でなければなりません。同じ値を持つcase
ラベルを複数記述することはできません。 - nullの扱い:
switch
文でString
型を使用する場合、条件式の結果がnull
であるとNullPointerException
がスローされます。そのため、null
を適切にハンドリングする必要があります。