一些类框架(如bean)填充的类.所以你不能保证所有的字段设置.
看看例子:标记为@Entity的类通常有Integer id字段. hashCode可以写成:
public int hashCode() { return id.hashCode(); }
但defencive代码可能看起来像:
public int hashCode() { return (id != null) ? id.hashCode() : 0; }
在hashCode和equals函数中尝试使用{…} catch(Exception e),需要对空或环绕码进行写入检查吗?
我没有任何辩护编码的理由是这样的情况,因为它隐藏将不一致的对象放在集合中并导致更迟的错误.我在这个位置错了吗?
更新我写了这样的代码:
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)
解决方法
一般来说,答案是“依赖”.
>如果你不应该看到该字段的null类的实例,那么允许抛出一个NPE是合理的. NPE表示错误;即您的非正式不变量被破坏的情况.
>如果在某种情况下可以合理地期望具有null的实例,那么您应该处理null情况而不会抛出异常.
在这种特殊情况下,如果对象尚未被持久化,那么您明显地处理了id字段可以为null的对象.这是一个棘手的问题:
>如果你不允许空值为id,那么你必须小心,不要把非持久性对象放入散列表.
>如果你允许null为id,那么你有问题,如果你添加一个对象到一个哈希表,然后坚持它,哈希码可能会改变导致破坏哈希表.所以,现在你需要通过在瞬态字段中记录对象的hashcode值来防御它.并且大致相同的问题发生在等于.如果对象持久化时,如果相等性发生变化,那么最好不要将持久密钥和非持久密钥混合在同一哈希表中.
考虑到所有这一切,我建议要么抛出NPE,要么不使用id / hashcode中的id字段.