我试图通过在多个线程中使用相同的SimpleDateFormat实例来复制错误。但是我遇到了另一个问题而没有找到任何答案。
这个简单的代码块复制了我所看到的问题。
DateFormat d1 = new SimpleDateFormat("ddMMyyyy");
DateFormat d2 = new SimpleDateFormat("ddMMyyyy");
DateFormat d3 = new SimpleDateFormat("ddMMyy");
System.out.println("d1 = " + d1);
System.out.println("d2 = " + d2);
System.out.println("d3 = " + d3);
java 7(1.7_0_21)下的此操作结果如下
d1 = java.text.SimpleDateFormat@c5bfbc60
d2 = java.text.SimpleDateFormat@c5bfbc60
d3 = java.text.SimpleDateFormat@b049fd40
正如您所看到的,虽然我正在为d1和d2创建新对象,但它们最终会成为相同的引用。由于模式不同,d3最终成为一个新实例。
java compile / runtime是否执行此优化?任何指针都会有所帮助
答案 0 :(得分:14)
SimpleDateFormat
或DateFormat
(SimpleDateFormat
超类)和Format
(DateFormat
超类)已实施toString()
,因此{{1实际执行toString()
类,其代码为:
Object
现在,生成public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
hashCode:
SimpleDateFormat
这意味着,如果您使用相同的public int hashCode()
{
return pattern.hashCode();
// just enough fields for a reasonable distribution
}
创建了大量SimpleDateFormat
个实例,就像您的情况一样,它们将具有相同的pattern
,因此{对于这些实例,{1}}将返回相同的内容。
此外,正如rixmath发现的那样,具有相同hashCode
的{{1}}个实例也将是相同的。
答案 1 :(得分:6)
SimpleDateFormat
实际上通过返回模式的哈希码来实现hashCode
。
您可以使用System.identityHashCode()
验证实际上有不同的对象:
System.out.println("d1 = " + d1 + " / " + System.identityHashCode(d1));
System.out.println("d2 = " + d2 + " / " + System.identityHashCode(d2));
System.out.println("d3 = " + d3 + " / " + System.identityHashCode(d3));
这将打印3个不同的值。
答案 2 :(得分:5)
它们是不同的实例,试试这个
DateFormat d1 = new SimpleDateFormat("ddMMyyyy");
DateFormat d2 = new SimpleDateFormat("ddMMyyyy");
System.out.println(d1 == d2);
打印
false
对于相同的java.text.SimpleDateFormat@c5bfbc60
,它们基于类名和hashCode。根据Object.hashCode API,它不一定返回不同对象的不同值