CodeCoachその他のアドバイス

CodeCoachから提供されるその他のアドバイスには、3種類あります。

定数使用のため起こりえないコードの検出
CodeCoachにより、コンパイラより少し詳しい無効コードの検出が可能です。

CodeCoachでは、次のように、条件および例外ブロックにおける無効コードのブロックを検出できます。


int i,j; i = 1; j = 2; if ( i + j == 5) { // Because 1 + 2 can never equal 5, // anything in this block would be dead code. }

次のような例外ブロックの無効コードも検出します。


try { i = j + 3; } catch (Exception e) { // This is dead code because no // instruction in the try can cause // an exception }

次のSnippetでは、次のような部分的無効コードも検出します。


int i,j,k; i=2; j=3; k=(i==3)?i-j:i+j;

この場合、CodeCoachにより、iが3になることはないためi-jが無効コードになることが検出されます。

検出された無効コードを削除する際は注意してください。CodeCoachのアドバイスに従って例外ブロックからコードを削除し、変更した場合、意図しない結果が生じる場合があります。

無効コード検出のキーワードはCDEAです。

定数値による不変オブジェクト割当ての検出
java.lang.Stringjava.awt.Colorなどの一部のJavaクラスは不変です。不変クラスのインスタンスが割り当てられると、その値は変更できません。

そのような不変オブジェクトが繰り返し使用される場合、CodeCoachでは、このオブジェクトのstatic finalインスタンスをクラスのstaticイニシャライザに作成するようアドバイスします。これで、プログラムのメモリーを節約し、パフォーマンスを改善できます。

たとえば、次のコードがあるとします。


class foo { void paint() { int i; for (i=0; i<100; i++) { bar(i, new Color(1,2,3)); } } }

このコードでは、paintメソッドがコールされるたびに、java.awt.Colorのインスタンスが100個作成されます。barメソッドによりこの値が参照可能なリファレンスに保存される場合、これらの各インスタンスは保持されます。

同じクラスのより効率的なバージョンとして、次のものがあります。


class foo { private static final Color MyColor = new Color(1,2,3); void paint() { int i; for (i=0; i<100; i++) { bar(i, MyColor); } } }

この場合は、java.awt.Colorインスタンスが1つだけ作成されます。

オブジェクトを同期化処理に使用する場合、このアドバイスの使用には注意が必要です。static finalフィールドを作成すると、同期化の対象がオブジェクト・インスタンスのみではなく、処理全体になります。

不変オブジェクトの繰返しインスタンス検出のキーワードはACSTです。

非効率なinstanceof成功率100%
非効率なinstanceof成功率0%

instanceof操作では、1つのオブジェクトが別のオブジェクトのサブクラスであるかどうかを判別できます。

instanceof文が常にtrueまたは常にfalseの場合、この操作は不要で、負荷がかかります。


private static final void test_INST() { BufferedReader r1; try { r1 = new BufferedReader(new FileReader("C:\\boot.ini")); Object obj = r1; if (obj instanceof Reader) { //success rate 100% System.out.println("It's a Reader!"); } if (obj instanceof Writer) { //success rate 0% System.out.println("It's a Writer!"); } } catch (IOException e) { System.out.println("Ooops!"); } }

この例では、objが常にReaderであることは明らかです。実際のアプリケーションでは、状況はそれほど明らかではありません。

次に、もう1つ一般的な状況を示します。


1 : void foo(Vector v) 2 : { 3 : int i; 4 : 5 : for (i = 0; i < v.size(); i++) 6 : { 7 : Object o = v.elementAt(i); 8 : if (o instanceof MyClass) 9 : { 10 : MyClass m = (MyClass) o; 11 : m.bar(); 12 : } 13 : else 14 : { 15 : abortProgram(); 16 : } 17 : } 18 : }

この場合、fooメソッドに提供されるVectorは、MyClassのインスタンスのみを含むよう設計されています。他のものが含まれている場合、それは致命的なバグです。このバージョンのfooは非常に保守的で、すべてのケースをテストします。ただし、負荷のかかる操作が8行目(instanceof)および10行目(VMにより内部的に実行されるcheckcast)で2回実行されます。同じメソッドの効率的なバージョンを次に示します。


1 : void foo(Vector v) 2 : { 3 : int i; 4 : try 5 : { 6 : for (i = 0; i < v.size(); i++) 7 : { 8 : MyClass m = (MyClass) v.elementAt(i); 9 : m.bar(); 10 : } 11 : { 12 : Catch (ClassCastException e) 14 : { 15 : abortProgram(); 16 : } 18 : }

ここでは、負荷のかかるテストは8行目で1回だけ実行され、エラーが発生した場合、プログラムは中止されます。コール側階層の高いレベルで捕捉することもできます。

instanceof操作が常に失敗する場合も、同様です。プログラム・ロジックのエラーである可能性があります。

このようなinstanceof操作検出のキーワードはINSTです。


プロジェクトのCodeCoach処理
CodeCoachアドバイス・タイプを使用可または使用不可に設定
CodeCoachアドバイス・レベルの設定
コマンドラインからのCodeCoachの使用
「プロジェクトの設定」ダイアログ - 「CodeCoach」ページ