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. }

また、CodeCoachでは、次のように例外ブロック内で不要コードが検出されます。


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

次のSnippetでは、CodeCoachによって部分的な不要コードが検出されます。


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

この場合、iは3にならないため、i-jは不要コードであることがCodeCoachによって検出されます。

検出された不要コードを削除する場合は注意が必要です。CodeCoachアドバイスに基づいて例外ブロックからコードを削除してからコードを変更すると、意図しない結果が発生することがあります。

不要コードを検出するキーワードは、CDEAです。

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

このような不変オブジェクトが繰り返し使用される場合は、CodeCoachでは、クラスのstaticイニシャライザでこのオブジェクトのstatic finalインスタンスを作成することを推奨しています。これにより、メモリーが確保されてプログラムのパフォーマンスが向上します。

次のコード例を考えてみます。


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); } } }

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

同期化プロセスでオブジェクトを使用する場合は、このアドバイスを使用するときに注意が必要です。この場合、static finalフィールドを作成すると、同期はオブジェクト・インスタンスに対してローカルになるのではなく、プロセスに対してグローバルになります。

繰り返される不変オブジェクトのインスタンスを検出するキーワードは、ACSTです。

instanceofの成功率が不十分です : 100%
instanceofの成功率が不十分です : 0%

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

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が常にリーダーであることがわかります。実際のアプリケーションでは、通常、状況はこれほど顕著ではありません。

別の一般的な状況は、次のとおりです。


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のインスタンスのみを含むように設計されています。Vectorに他のインスタンスが含まれている場合は、不具合である可能性が非常に高く、致命的です。このバージョンのfooは非常に慎重であり、すべてのケースをテストします。ただし、コストがかかる操作が2度、8行目(instanceof)と10行目(VMによって内部で実行されるcheckcast)で実行されています。同じメソッドのより効率的なバージョンは、次のとおりです。


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の使用