ショートサーキット
日本語 | 短絡回路 |
英語 | short circuit |
ふりがな | しょーとさーきっと |
フリガナ | ショートサーキット |
左オペランドのみ評価し、右オペランドを評価しないこと。
&&演算子と||演算子は、左オペランドを先に評価する。
その際左オペランドが、&&演算子はfalse、||演算子はtrueの場合には、右オペランドを評価しない。
つまり「右オペランドの評価を省略する」ため、これを「ショートサーキット」「短絡評価」と言う。また&&演算子と||演算子を「ショートサーキット演算子」「短絡演算子」とも言う。
&&演算子の場合、左オペランドを評価した結果がfalseの場合に右オペランドを評価しない。
これは、右オペランドの結果に関わらず結果はfalseとなり、右オペランドの評価が「必要ない」ためである。
||演算子の場合、左オペランドを評価した結果がtrueの場合に右オペランドを評価しない。
これは、右オペランドの結果に関わらず結果はtrueとなり、右オペランドの評価が「必要ない」ためである。
右オペランドで何らかの処理を行っている場合、その処理そのものが行われない。
ショートサーキットを使用することでプログラムを簡略化することができる場合がある。
ただし、この2つの演算子がショートサーキットを行うことを知らない場合、処理されるはずなのに処理されない、といったバグを生む可能性ががあるため注意すること。
&&演算子と||演算子は、左オペランドを先に評価する。
その際左オペランドが、&&演算子はfalse、||演算子はtrueの場合には、右オペランドを評価しない。
つまり「右オペランドの評価を省略する」ため、これを「ショートサーキット」「短絡評価」と言う。また&&演算子と||演算子を「ショートサーキット演算子」「短絡演算子」とも言う。
&&演算子の場合、左オペランドを評価した結果がfalseの場合に右オペランドを評価しない。
これは、右オペランドの結果に関わらず結果はfalseとなり、右オペランドの評価が「必要ない」ためである。
||演算子の場合、左オペランドを評価した結果がtrueの場合に右オペランドを評価しない。
これは、右オペランドの結果に関わらず結果はtrueとなり、右オペランドの評価が「必要ない」ためである。
右オペランドで何らかの処理を行っている場合、その処理そのものが行われない。
ショートサーキットを使用することでプログラムを簡略化することができる場合がある。
ただし、この2つの演算子がショートサーキットを行うことを知らない場合、処理されるはずなのに処理されない、といったバグを生む可能性ががあるため注意すること。
// Sample.java
public class Sample
{
public static void main( String[] args )
{
boolean b;
// &&演算子はショートサーキットが行われます。
b = false && getTrue();
// (何も出力されません)
// この時、getTrue()メソッドは呼ばれません。
// &&演算子は左オペランドから評価します。そして、
// 左オペランドがfalseの場合、右オペランドに関わらず
// 結果はfalseとなるため、右オペランドは評価されません。
// だからgetTrue()メソッドが呼ばれないわけです。
// ||演算子はショートサーキットが行われます。
b = true || getTrue();
// (何も出力されません)
// この時、getTrue()メソッドは呼ばれません。
// ||演算子は左オペランドから評価します。そして、
// 左オペランドがtrueの場合、右オペランドに関わらず
// 結果はtrueとなるため、右オペランドは評価されません。
// だからgetTrue()メソッドが呼ばれないわけです。
// ショートサーキットの利用例のひとつに、nullチェックがあります。
Boolean aBoolean = null;
if( ( aBoolean != null ) && ( aBoolean.booleanValue() == true ) )
{
System.out.println( "aBooleanはtrueです。" );
}
// (何も出力されません)
// 「( aBoolean != null )」がfalseとなるため、ショートサーキットが働き
// 「( aBoolean.booleanValue() == true ) 」が評価されません。
// そのため、もし「aBoolean.booleanValue()」を呼び出そうとしたら
// NullPointerException例外が投げられますが、それを避けることが
// できます。
// nullチェックは行う回数が多いので、こういったテクニックがよく
// 使われます。
// ありがちなバグの例として以下のようなものがあります。
boolean b2 = true;
b = true || ( b2 = false );
System.out.println( b2 );
// true
// 「( b2 = false )」が評価されていないため、b2にfalseが
// 代入されていません。
// こういったバグを生まないよう、&&演算子と||演算子では
// 右オペランドの式に副作用がないか確認するくせをつけましょう。
}
/**
* 呼ばれたかどうか確認するためのメソッド。
* 「Sample#getTrue()」を出力し、必ずtrueを返します。
*/
private static boolean getTrue()
{
System.out.println( "Sample#getTrue()" );
return true;
}
}
public class Sample
{
public static void main( String[] args )
{
boolean b;
// &&演算子はショートサーキットが行われます。
b = false && getTrue();
// (何も出力されません)
// この時、getTrue()メソッドは呼ばれません。
// &&演算子は左オペランドから評価します。そして、
// 左オペランドがfalseの場合、右オペランドに関わらず
// 結果はfalseとなるため、右オペランドは評価されません。
// だからgetTrue()メソッドが呼ばれないわけです。
// ||演算子はショートサーキットが行われます。
b = true || getTrue();
// (何も出力されません)
// この時、getTrue()メソッドは呼ばれません。
// ||演算子は左オペランドから評価します。そして、
// 左オペランドがtrueの場合、右オペランドに関わらず
// 結果はtrueとなるため、右オペランドは評価されません。
// だからgetTrue()メソッドが呼ばれないわけです。
// ショートサーキットの利用例のひとつに、nullチェックがあります。
Boolean aBoolean = null;
if( ( aBoolean != null ) && ( aBoolean.booleanValue() == true ) )
{
System.out.println( "aBooleanはtrueです。" );
}
// (何も出力されません)
// 「( aBoolean != null )」がfalseとなるため、ショートサーキットが働き
// 「( aBoolean.booleanValue() == true ) 」が評価されません。
// そのため、もし「aBoolean.booleanValue()」を呼び出そうとしたら
// NullPointerException例外が投げられますが、それを避けることが
// できます。
// nullチェックは行う回数が多いので、こういったテクニックがよく
// 使われます。
// ありがちなバグの例として以下のようなものがあります。
boolean b2 = true;
b = true || ( b2 = false );
System.out.println( b2 );
// true
// 「( b2 = false )」が評価されていないため、b2にfalseが
// 代入されていません。
// こういったバグを生まないよう、&&演算子と||演算子では
// 右オペランドの式に副作用がないか確認するくせをつけましょう。
}
/**
* 呼ばれたかどうか確認するためのメソッド。
* 「Sample#getTrue()」を出力し、必ずtrueを返します。
*/
private static boolean getTrue()
{
System.out.println( "Sample#getTrue()" );
return true;
}
}
// Sample.java public class Sample { public static void main( String[] args ) { boolean b; // &&演算子はショートサーキットが行われます。 b = false && getTrue(); // (何も出力されません) // この時、getTrue()メソッドは呼ばれません。 // &&演算子は左オペランドから評価します。そして、 // 左オペランドがfalseの場合、右オペランドに関わらず // 結果はfalseとなるため、右オペランドは評価されません。 // だからgetTrue()メソッドが呼ばれないわけです。 // ||演算子はショートサーキットが行われます。 b = true || getTrue(); // (何も出力されません) // この時、getTrue()メソッドは呼ばれません。 // ||演算子は左オペランドから評価します。そして、 // 左オペランドがtrueの場合、右オペランドに関わらず // 結果はtrueとなるため、右オペランドは評価されません。 // だからgetTrue()メソッドが呼ばれないわけです。 // ショートサーキットの利用例のひとつに、nullチェックがあります。 Boolean aBoolean = null; if( ( aBoolean != null ) && ( aBoolean.booleanValue() == true ) ) { System.out.println( "aBooleanはtrueです。" ); } // (何も出力されません) // 「( aBoolean != null )」がfalseとなるため、ショートサーキットが働き // 「( aBoolean.booleanValue() == true ) 」が評価されません。 // そのため、もし「aBoolean.booleanValue()」を呼び出そうとしたら // NullPointerException例外が投げられますが、それを避けることが // できます。 // nullチェックは行う回数が多いので、こういったテクニックがよく // 使われます。 // ありがちなバグの例として以下のようなものがあります。 boolean b2 = true; b = true || ( b2 = false ); System.out.println( b2 ); // true // 「( b2 = false )」が評価されていないため、b2にfalseが // 代入されていません。 // こういったバグを生まないよう、&&演算子と||演算子では // 右オペランドの式に副作用がないか確認するくせをつけましょう。 } /** * 呼ばれたかどうか確認するためのメソッド。 * 「Sample#getTrue()」を出力し、必ずtrueを返します。 */ private static boolean getTrue() { System.out.println( "Sample#getTrue()" ); return true; } }