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.
}
また、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.String
とjava.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
操作を使用すると、あるオブジェクトが別のオブジェクトのサブクラスであるかどうかを判別できます。
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
です。
Copyright © 1997, 2007, Oracle. All rights reserved.