new SimpleDateFormat always returns same reference

2020-04-03 01:19发布


I was trying to replicate a bug by using the same instance of SimpleDateFormat across multiple threads. However I got stuck with another problem and did not find any answers to it.

This simple code block replicates the issues I am seeing.

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);

The results of this operations under java 7 (1.7_0_21) is as follows

d1 = java.text.SimpleDateFormat@c5bfbc60
d2 = java.text.SimpleDateFormat@c5bfbc60
d3 = java.text.SimpleDateFormat@b049fd40

As you can see that although I am creating new objects for d1 and d2 they end up being the same reference. d3 ends up being a new instance as pattern is different.

Does java compile/runtime do this optimization? Any pointers will be helpful

标签: java
3条回答
家丑人穷心不美
2楼-- · 2020-04-03 01:27

They are different instances, try this

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

it prints

false

as for the same java.text.SimpleDateFormat@c5bfbc60, they are based on class name and hashCode. According to Object.hashCode API it does not necessarily return distinct values for distinct objects

查看更多
狗以群分
3楼-- · 2020-04-03 01:37

SimpleDateFormat nor DateFormat (SimpleDateFormat superclass) nor Format (DateFormat superclass) have a toString() implemented, so the toString() from the Object class is actually executed, whose code is :

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

Now, SimpleDateFormat hashCode is generated:

public int hashCode()
{
    return pattern.hashCode();
    // just enough fields for a reasonable distribution
}

Which means that if you create numerous SimpleDateFormat instances with the same pattern, like in your case, they will have the same hashCode and hence toString() will return the same for these instances.

Moreover, as it has been spotted by rixmath, SimpleDateFormat instances with the same pattern will also be equal.

查看更多
霸刀☆藐视天下
4楼-- · 2020-04-03 01:47

SimpleDateFormat actually implements hashCode by returning the hashcode of the pattern.

You can verify that there are actually distinct objects by using 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));

This will print 3 different values.

查看更多
登录 后发表回答