13

フレームワーク(Beanなど)で満たされた一部のクラス。したがって、すべてのフィールドが設定されていることを保証することはできません。

@Entity例を見てください:通常としてマークされたクラスにはInteger idフィールドがあります。hashCode次のように書くことができます:

public int hashCode() {
    return id.hashCode();
}

ただし、防御コードは次のようになります。

public int hashCode() {
    return (id != null) ? id.hashCode() : 0;
}

try { ... } catch (Exception e)inhashCodeおよびequals関数を使用してnullまたはサラウンドコードの書き込みチェックを行う必要がありますか?

一貫性のないオブジェクトをコレクションに配置することを隠し、遅延エラーにつながるため、防御コーディングがそのような場合であるという議論はありません。私はこの立場で間違っていますか?

UPDATE私はそのようなコードを書きました:

import java.util.*;

class ExceptionInHashcode {

    String name;

    ExceptionInHashcode() { }
    ExceptionInHashcode(String name) { this.name = name; }

    public int hashCode() {
        // throw new IllegalStateException("xxx");
        return this.name.hashCode();
    }

    public static void main(String args[]) {
        Hashtable list = new Hashtable();
        list.put(new ExceptionInHashcode("ok"), 1);
        list.put(new ExceptionInHashcode(), 2); // fail
        System.out.println("list.size(): " + list.size());
    }
}

そしてそれを実行します:

java -classpath . ExceptionInHashcode
Exception in thread "main" java.lang.NullPointerException
        at ExceptionInHashcode.hashCode(ExceptionInHashcode.java:12)
        at java.util.Hashtable.hash(Hashtable.java:262)
        at java.util.Hashtable.put(Hashtable.java:547)
        at ExceptionInHashcode.main(ExceptionInHashcode.java:18)

オブジェクトが間違った状態にある場合、ゼロを返す代わりに、エラーを早期に見つけることができると思います...

4

4 に答える 4

8

一般的に、答えは「場合による」です。

  • そのフィールドのクラスのインスタンスがまったく表示されない場合は、NPE のスローを許可するのが妥当です。nullNPE はバグを示します。つまり、非公式の不変条件が壊れている状況です。

  • を持つインスタンスが合理的に期待できる状況がある場合は、例外をスローせずにケースにnull対処する必要があります。null


idこの特定のケースでは、オブジェクトがまだ永続化されていない場合、フィールドが null になる可能性があるオブジェクトを扱っているようです。これはトリッキーな問題を提示します:

  • nullを許可しない場合はid、非永続オブジェクトをハッシュ テーブルに入れないように注意する必要があります。

  • を許可するnullid、オブジェクトをハッシュ テーブルに追加してそれを永続化すると、hashcodeが変更されてハッシュ テーブルが破損する可能性があるという問題があります。そのため、一時的なフィールドにオブジェクトのハッシュコード値をメモすることで、それを防御する必要があります。とほぼ同じ問題が発生しequalsます。オブジェクトが永続化されたときに等価性が変化する場合は、永続化されたキーと永続化されていないキーを同じハッシュ テーブルに混在させない方がよいでしょう。

これらすべてを考慮して、その NPE をスローするか、 /のidフィールドを使用しないことをお勧めします。equalshashcode

于 2013-03-01T07:12:38.060 に答える
8

私は個人的に nullity をチェックし、メソッドが例外なく常に返されるようにします。

equals実行時例外は文書化されていないことが多く、どこでもスローされる可能性がありますが、一般的にandによってスローされるのは良くないと思いますhashCode。一方で、完全に人口が集中する前にマップに配置されることについてのあなたの主張は確かにわかります...しかし、他方では、どこequalsで呼び出されるかを本当に知るのは困難です.

lc がコメントで述べているように、本当に例外をスローしたい場合は、「デフォルトで」a をスローして、単にあなたのように見せるIllegalStateExceptionよりも、これが意図的なものであることを明確にするためにan をスローする方がはるかに良いでしょう。 NullReferenceExceptionnullのシナリオについては考えていませんでした。

于 2013-03-01T06:55:38.563 に答える
2

オブジェクトの状態を検証するには、Bean 検証フレームワークを使用して、オブジェクトの状態が有効であることを確認する必要があります。

No hashcode および equals メソッドは、例外をスローしてはなりません。

equalsメソッドには、nullity のチェックが必要です。また、オブジェクトが作成されたときに、オブジェクトが有効な状態であることを確認するのは作成者の責任であるためhashCode、例外をスローする必要はありません。そのために、Bean 検証を使用できます。IMO。

更新: Bean を作成する Bean フレームワークを使用しているため、Bean の検証に依存する必要があります。ただし、それ以外の場合は、有効なインスタンスのみが作成さFactoryれることを確認するために、オブジェクトを作成する側の責任である必要があります。

于 2013-03-01T06:53:09.310 に答える
1

コードでヌル ポインター例外が発生することは決してありません。決して。特に、独自のコードの外で頻繁に使用される関数では。hashcode equals toString例外をスローしてはなりません。

ところで: id をハッシュコードとしていつでも返すことができます。

于 2013-03-01T06:55:35.813 に答える