コードの質が低いと、予測できない動作につながります。ユーザーの視点には、それがしばしば使い勝手の悪さとなって現れます。攻撃者にとっては、予期せぬ方法でシステムにストレスを与える機会となります。
void clean_up()
{
char tmp[256];
...
free(tmp);
return;
}
System.Object.Equals()
を上書きするためのものです。
public boolean Equals(string obj) {
...
}
System.Object.Equals()
は、object
タイプの引数を取るため、メソッドがコールされることはありません。Object.equals()
を上書きするためのものです。
public boolean equals(Object obj1, Object obj2) {
...
}
Object.equals()
は単一引数のみを受け取るため、Example 1
のメソッドがコールされることはありません。ISerializable
インターフェイスを実装しているが、[Serializable]
属性を宣言していないクラスはシリアライズされません。[Serializable]
属性が宣言されているすべてのオブジェクトのシリアライズを許可します。.NET フレームワークにより定義されるデフォルトのシリアライズメソッドを使用してクラスがシリアライズ可能な場合、オブジェクトを正しくシリアライズするためにこれは必要十分条件となります。クラスで独自のシリアライズメソッドが必要となる場合には、ISerializable
インターフェイスを実装する必要もあります。ただし、クラスは [Serializable]
属性をここでも宣言する必要があります。CustomStorage
クラスは ISerializable
インターフェイスを実装します。しかし、このクラスは [Serializable]
属性を宣言していないため、シリアライズされません。
public class CustomStorage: ISerializable {
...
}
java.io.Serializable
を実装している内部クラスは、問題が発生したり、外部クラスから情報が漏えいする可能性があります。
...
class User implements Serializable {
private int accessLevel;
class Registrator implements Serializable {
...
}
}
Example 1
では、内部クラス Registrator
がシリアライズされると、外部クラス User
からのフィールド accessLevel
もシリアライズされます。synchronized
を宣言した親クラスは、複数のスレッドが同じインスタンスにアクセスするときに、正しい動作を保証します。すべての上書きメソッドを、synchronized
として宣言する必要があります。そうしないと、予期せぬ動作が発生する可能性があります。Foo
がクラス Bar
を上書きしていますが、メソッド synchronizedMethod
を synchronized
に宣言していません。
public class Bar {
public synchronized void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
public class Foo extends Bar {
public void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
Foo
のインスタンスが、タイプ Bar
にキャストされる可能性があります。同じインスタンスが 2 つのスレッドに指定されており、synchronizedMethod
が繰り返し実行される場合、動作が予期できなくなります。obj.Equals(null)
は常に false となります。Equals()
メソッドを使用してオブジェクトを null
と比較します。Equals()
メソッドのコントラクトでは、この比較で常に false が戻される必要があります。obj.equals(null)
は常に false となります。equals()
メソッドを使用してオブジェクトを null
と比較します。オブジェクトが null
ではないため、この比較は常に false を返します。(オブジェクトが null
の場合、プログラムは NullPointerException
を発生させます)。pthread_exit()
をコールせずに生成されたスレッドより前に親プロセスが実行を終了すると、親プロセスの main()
関数から pthread_create()
をコールして生成されたスレッドは予定より早く終了します。pthread_exit()
をコールすることで、親プロセスのすべてのスレッドが実行を完了するまで親プロセスが終了せずに実行しつづけることを保証できます。または、親プロセスはすべての子スレッドで pthread_join
をコールして、プロセスが終了する前に確実に子スレッドが完了するようにできます。pthread_create()
を使用して、スレッドを作成して正常に終了しています。main()
関数が戻るときまでに、子スレッドがその実行を終了していない場合は、予定より早く実行を終了することになります。
void *Simple(void *threadid)
{
...
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int rc;
pthread_t pt;
rc = pthread_create(&pt, NULL, Simple, (void *)t);
if (rc){
exit(-1);
}
}