2013-05-24 18 views
8


Tôi đã cố gắng sao chép một lỗi bằng cách sử dụng cùng một cá thể của SimpleDateFormat trên nhiều luồng. Tuy nhiên tôi đã bị mắc kẹt với một vấn đề khác và không tìm thấy bất kỳ câu trả lời cho nó.SimpleDateFormat mới luôn trả về cùng một tham chiếu cho một dateFormat

Khối mã đơn giản này sao chép các vấn đề tôi thấy.

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

Kết quả của hoạt động này dưới java 7 (1.7_0_21) là như sau

d1 = [email protected] 
d2 = [email protected] 
d3 = [email protected] 

Như bạn có thể thấy rằng mặc dù tôi đang tạo ra các đối tượng mới cho d2 d1 và họ kết thúc là cùng tài liệu tham khảo. d3 kết thúc là một thể hiện mới vì mô hình là khác nhau.

Trình biên dịch/thời gian chạy java có thực hiện tối ưu hóa này không? Bất kỳ con trỏ sẽ rất hữu ích

+2

Chúng thực sự là cùng một cá thể (với '==')? – assylias

+2

Và để trả lời câu hỏi cuối cùng: không, một 'mới' trong Java sẽ ** luôn luôn ** dẫn đến một đối tượng mới (trừ khi nó dẫn đến một ngoại lệ). JVM không được phép tối ưu hóa điều đó. –

Trả lời

14

SimpleDateFormat cũng không DateFormat (SimpleDateFormat lớp cha) cũng không Format (DateFormat lớp cha) đã một toString() thực hiện, do đó toString() từ lớp Object được thực sự thực hiện, mà mã là:

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

Bây giờ , SimpleDateFormat hashCode được tạo:

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

Tôi ans rằng nếu bạn tạo nhiều trường hợp SimpleDateFormat với cùng một pattern, giống như trong trường hợp của bạn, chúng sẽ có cùng một số hashCode và do đó toString() sẽ trả về giống nhau cho những trường hợp này.

Hơn nữa, vì nó đã được phát hiện bởi rixmath, SimpleDateFormat trường hợp với cùng một pattern cũng sẽ bằng nhau.

+0

Tôi nghĩ bạn không nhận được câu hỏi của mình.Anh ta hỏi tại sao cả hai tham chiếu (d1, d2) trỏ tới cùng một đối tượng SimpleDateFormat. Hãy xem mã băm của nó. Nó giống nhau. –

+0

@Ankur mặc dù cùng một mã băm không hàm ý cùng một trường hợp. – assylias

+0

Đúng, nhưng đó không phải là câu hỏi. Anh ta bối rối vì sao hai biến trỏ đến cùng một đối tượng khi người ta mong đợi khác nhau. http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#toString() –

5

Họ là những trường hợp khác nhau, hãy thử này

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

nó in

false 

như cho cùng [email protected], chúng được dựa trên tên lớp và hashCode. Theo API Object.hashCode, nó không nhất thiết trả về các giá trị riêng biệt cho các đối tượng riêng biệt

6

SimpleDateFormat thực hiện thực hiện hashCode bằng cách trả về mã băm của mẫu.

Bạn có thể xác minh rằng thực sự có đối tượng riêng biệt bằng cách sử dụng 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)); 

này sẽ in 3 giá trị khác nhau.

+1

Mã băm nhận dạng của hai đối tượng riêng biệt cũng có thể giống nhau. Toán tử '==' nên được sử dụng để xác minh rằng hai đối tượng là các đối tượng riêng biệt. – SpaceTrucker

+0

@SpaceTrucker: đúng vậy, nó * có thể * giống nhau, nhưng rất khó xảy ra. –

Các vấn đề liên quan