问题描述
一些由框架填充的类(如 bean).所以你不能保证所有的字段都设置了.
Some classes filled by frameworks (like beans). So you can't guaranty that all fields set.
查看示例:标记为 @Entity
的类通常具有 Integer id
字段.hashCode
可以写成:
Look to example: classes marked as @Entity
usually have Integer id
field. hashCode
can be written as:
public int hashCode() {
return id.hashCode();
}
但防御性代码可能如下所示:
but defencive code may look like:
public int hashCode() {
return (id != null) ? id.hashCode() : 0;
}
我是否需要在 hashCode
和 equals
中使用 try { ... } catch (Exception e)
编写空代码或环绕代码检查功能?
Do I need write checks for null or surround code with try { ... } catch (Exception e)
in hashCode
and equals
functions?
我对这种情况下的防御性编码没有任何论据,因为它隐藏了将不一致的对象放入集合并导致后期错误的情况.我在这个位置上错了吗?
I have no arguments for defencive coding is such case because it hide putting inconsistent objects to collections and lead to late errors. Am I wrong in this position?
更新我写了这样的代码:
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)
我认为如果对象处于错误状态,我可以及早发现错误而不是返回零......
I think that I can find error early instead of returning zero if object is in wrong state...
推荐答案
一般来说,答案是视情况而定".
In general, the answer is "it depends".
如果您应该从不看到该字段具有
null
的类的实例,那么允许抛出 NPE 是合理的.NPE 表示存在错误;即您的非正式不变量被破坏的情况.
If you should never see instances of the class with
null
for that field, then it is reasonable to allow an NPE to be thrown. The NPE indicates a bug; i.e. a situation where your informal invariant is broken.
如果在某些情况下可以合理预期具有 null
的实例,那么您应该处理 null
情况而不抛出异常.
If there are circumstances where an instance with a null
could reasonably expected, then you should deal with the null
case without throwing an exception.
在这种特殊情况下,如果对象尚未持久化,您显然正在处理 id
字段可以为 null 的对象.这提出了一个棘手的问题:
In this particular case, you are apparently dealing with objects where the id
field can be null if the object hasn't been persisted yet. This presents a tricky problem:
如果您不允许
id
为null
,那么您必须小心不要将非持久对象放入哈希表中.
If you don't allow
null
for theid
, then you have to be careful not to put non-persistent objects into a hash table.
如果你确实允许 null
作为 id
,那么你会遇到一个问题,如果你将一个对象添加到一个哈希表中,然后将它持久化,hashcode
可能会发生变化,导致哈希表损坏.因此,现在您需要通过在瞬态字段中记住对象的哈希码值来防御这种情况.equals
也会出现大致相同的问题.如果持久化对象时相等性发生变化,那么最好不要在同一个哈希表中混合持久化和非持久化键.
If you do allow null
for the id
, then you have the problem that if you add an object to a hash table and THEN persist it, the hashcode
may change leading to breakage of the hash table. So, now you need to defend against THAT ... by memoising the object's hashcode value in a transient field. And roughly the same problem occurs with equals
. If equality changes when an object is persisted, then you had better not mix persisted and non-persisted keys in the same hash table.
考虑到所有这些,我建议要么抛出该 NPE,要么不使用 equals
/hashcode
中的 id
字段>.
Taking all of that into account, I'd advise to either throw that NPE, or not use the id
fields in equals
/ hashcode
.
这篇关于Java 中是否允许和接受 hashCode 和 equals 方法中的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!