2013-05-24 2 views
8


Я пытался реплицировать ошибку, используя тот же экземпляр SimpleDateFormat для нескольких потоков. Однако я столкнулся с другой проблемой и не нашел на ней никаких ответов.новый SimpleDateFormat всегда возвращает ту же ссылку для данной датыFormat

Этот простой кодовый блок реплицирует проблемы, которые я вижу.

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 = [email protected] 
d2 = [email protected] 
d3 = [email protected] 

Как вы можете видеть, что, хотя я создаю новые объекты для Д1 и Д2 они в конечном итоге то же самое Справка. d3 заканчивается тем, что является новым экземпляром, поскольку шаблон отличается.

Выполняет ли java компиляцию/выполнение во время этой оптимизации? Все указатели будут полезны

+2

Являются ли они на самом деле одним и тем же экземпляром (с '==')? – assylias

+2

И ответить на последний вопрос: no, 'new' в Java всегда будет ** приводить к появлению нового объекта (если только это не приведет к исключению). JVM не позволяет оптимизировать это. –

ответ

14

SimpleDateFormat ни DateFormat (SimpleDateFormat суперкласса), ни Format (DateFormat суперкласс) имеют toString() реализованы, поэтому toString() из Object класса фактически выполняются, код которого:

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

сейчас , SimpleDateFormat хэш-код генерируется:

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

Что меня что если вы создадите множество SimpleDateFormat экземпляров с теми же pattern, как и в вашем случае, они будут иметь то же самое hashCode и, следовательно, toString() вернет то же самое для этих случаев.

Кроме того, как было обнаружено rixmath, SimpleDateFormat экземпляры с одинаковыми pattern также будут равны.

+0

Я думаю, вы не получили его вопрос.Он спрашивает, почему обе ссылки (d1, d2) указывают на один и тот же объект SimpleDateFormat. Взгляните на его хэш-код. Это то же самое. –

+0

@ Ankur, хотя тот же hashcode не подразумевает такой же экземпляр. – assylias

+0

Правильно, но это не вопрос. Он озадачен тем, почему две переменные указывают на один и тот же объект, если можно ожидать по-другому. http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#toString() –

5

Это разные случаи, попробуйте это

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

печатает

false 

как за тот же [email protected], они основаны на имени класса и хэш-код. Согласно Object.hashCode API, он не обязательно возвращает отдельные значения для отдельных объектов.

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 различных значения.

+1

Идентификационный код хеширования двух разных объектов также может быть одинаковым. Вместо этого следует использовать оператор '==', чтобы проверить, что два объекта являются разными. – SpaceTrucker

+0

@SpaceTrucker: это правильно, он * может * быть одним и тем же, но это очень маловероятно. –