gav*_*koa 12 java exception equals hashcode nullpointerexception
一些类由框架填充(如bean).因此,您无法保证所有字段都已设置.
示例:标记为@Entity通常具有Integer id字段的类.hashCode可以写成:
public int hashCode() {
return id.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
但是defencive代码可能看起来像:
public int hashCode() {
return (id != null) ? id.hashCode() : 0;
}
Run Code Online (Sandbox Code Playgroud)
我是否需要使用try { ... } catch (Exception e)in hashCode和equals函数对null或环绕码进行写检查?
我没有关于defencive编码的论据就是这种情况,因为它隐藏了将不一致的对象隐藏到集合中并导致延迟错误.我错了吗?
更新我写了这样的代码:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
并运行它:
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)
Run Code Online (Sandbox Code Playgroud)
我认为如果对象处于错误的状态,我可以提前发现错误而不是返回零...
我会亲自检查无效并使方法总是返回,没有例外.
虽然运行时异常往往不记录,并可以在任何地方被抛出,我认为这将是普遍不佳的他们被抛出equals和hashCode.一方面,我完全可以看到你在完全填充之前放入地图的观点...但另一方面,很难真正知道equals将在哪里调用.
正如lc在评论中所说的那样,如果你真的想要抛出一个异常,那么抛出一个IllegalStateException明确表示这是故意的,而不是让它NullReferenceException被抛出"默认情况"会让它看起来像你只是更好没想到空场景.
一般来说,答案是"它取决于".
如果你永远不应该看到该类的实例null,那么允许抛出NPE是合理的.NPE表示一个错误; 即你的非正式不变量被打破的情况.
如果在某些情况下null可以合理地预期具有a的实例,那么您应该在null不抛出异常的情况下处理该情况.
在这种特殊情况下,您显然正在处理id如果对象尚未持久化,则该字段可以为null的对象.这提出了一个棘手的问题:
如果不允许null的id,那么你要小心,不要把非持久性对象到一个哈希表.
如果你允许null的id,那么你有问题,如果对象添加到哈希表,然后坚持它,则hashcode可能会改变导致哈希表的破损.所以,现在你需要通过在瞬态字段中记忆对象的哈希码值来防御这种情况.而且大致出现同样的问题equals.如果在持久化对象时更改了相等性,那么最好不要在同一个哈希表中混合使用持久密钥和非持久密钥.
考虑到所有这些因素,我建议要么抛弃NPE,要么不使用/中的id字段.equalshashcode
| 归档时间: |
|
| 查看次数: |
4837 次 |
| 最近记录: |