CodeCoachから提供されるその他のアドバイスには、3種類あります。
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.String
やjava.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
操作では、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
は非常に保守的で、すべてのケースをテストします。 ただし、負荷のかかる操作が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
です。
Copyright © 1997, 2004, Oracle. All rights reserved.