Java 对于给定的日期格式,新的SimpleDataFormat始终返回相同的引用

Java 对于给定的日期格式,新的SimpleDataFormat始终返回相同的引用,java,Java,我试图通过跨多个线程使用同一个SimpleDataFormat实例来复制一个bug。然而,我遇到了另一个问题,没有找到任何答案 这个简单的代码块复制了我看到的问题 DateFormat d1 = new SimpleDateFormat("ddMMyyyy"); DateFormat d2 = new SimpleDateFormat("ddMMyyyy"); DateFormat d3 = new SimpleDateFormat("ddMMyy"); System.out.println("


我试图通过跨多个线程使用同一个SimpleDataFormat实例来复制一个bug。然而,我遇到了另一个问题,没有找到任何答案

这个简单的代码块复制了我看到的问题

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编译/运行时是否执行此优化?任何指针都是有用的

SimpleDateFormat
DateFormat
SimpleDateFormat
超类)或
Format
DateFormat
超类)都实现了
toString()
,因此实际执行
对象
类中的
toString()
,其代码为:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
现在,
SimpleDataFormat
hashCode生成:

public int hashCode()
{
    return pattern.hashCode();
    // just enough fields for a reasonable distribution
}
这意味着,如果您使用相同的
模式创建多个
SimpleDataFormat
实例,就像在您的案例中一样,它们将具有相同的哈希代码
,因此
toString()
将为这些实例返回相同的值


此外,正如rixmath所发现的,
SimpleDateFormat
具有相同
模式的实例也将是相等的。
SimpleDateFormat
DateFormat
SimpleDateFormat
超类)或
Format
DateFormat
超类)都有
toString()
已实现,因此实际执行
对象
类中的
toString()
,其代码为:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
现在,
SimpleDataFormat
hashCode生成:

public int hashCode()
{
    return pattern.hashCode();
    // just enough fields for a reasonable distribution
}
这意味着,如果您使用相同的
模式创建多个
SimpleDataFormat
实例,就像在您的案例中一样,它们将具有相同的哈希代码
,因此
toString()
将为这些实例返回相同的值


此外,正如rixmath所发现的那样,具有相同模式的实例也将是相同的。

它们是不同的实例,请尝试以下操作

    DateFormat d1 = new SimpleDateFormat("ddMMyyyy");
    DateFormat d2 = new SimpleDateFormat("ddMMyyyy");
    System.out.println(d1 == d2);
它打印

false

对于相同的
java.text。SimpleDateFormat@c5bfbc60
,它们基于类名和哈希代码。根据Object.hashCode API,它不一定为不同的对象返回不同的值

它们是不同的实例,请尝试以下操作

    DateFormat d1 = new SimpleDateFormat("ddMMyyyy");
    DateFormat d2 = new SimpleDateFormat("ddMMyyyy");
    System.out.println(d1 == d2);
它打印

false

对于相同的
java.text。SimpleDateFormat@c5bfbc60
,它们基于类名和哈希代码。根据Object.hashCode API,它不一定返回不同对象的不同值

SimpleDataFormat
实际上是通过返回模式的hashCode来实现的

您可以使用以下方法验证是否确实存在不同的对象:


这将打印3个不同的值。

SimpleDataFormat
通过返回模式的hashCode实际实现了
hashCode

您可以使用以下方法验证是否确实存在不同的对象:



这将打印3个不同的值。

我想你没有理解他的问题。他在问为什么两个引用(d1,d2)都指向同一个SimpleDataFormat对象。看看它的哈希代码。是的,但这不是问题所在。他感到困惑,为什么两个变量指向同一个对象,而人们的期望却不同。谢谢在问这个问题之前,我应该多挖一点。它们确实是单独的参考。(刚刚调试了这段代码并找到了。)@assylias真的,我想我一直这么认为。@Ankur谢谢你指出这一点,我已经更新了答案。我想你没有明白他的问题。他在问为什么两个引用(d1,d2)都指向同一个SimpleDataFormat对象。看看它的哈希代码。是的,但这不是问题所在。他感到困惑,为什么两个变量指向同一个对象,而人们的期望却不同。谢谢在问这个问题之前,我应该多挖一点。它们确实是单独的参考。(刚刚调试了这段代码并找到了。)@assylias真的,我想我一直这么认为。@Ankur谢谢你指出这一点,我已经更新了答案他们实际上是同一个实例吗(使用
=
)?并回答最后一个问题:不,Java中的
new
总是会产生一个新对象(除非它导致异常)。JVM不允许对其进行优化。它们实际上是同一个实例(使用
=
)?并回答最后一个问题:否,Java中的
总是会产生一个新对象(除非它导致异常)。JVM不允许对其进行优化。两个不同对象的标识哈希代码也可能相同。应该使用
=
运算符来验证两个对象是否是不同的对象。@SpaceTrucker:没错,可能是相同的,但可能性不大。两个不同对象的标识哈希代码也可能相同。应该使用
=
操作符来验证两个对象是否是不同的对象。@SpaceTrucker:没错,可能是相同的,但可能性不大。