2013-09-24 33 views
32

Ai có thể giải thích những gì đang xảy ra?Khối tĩnh không được gọi là

public class MagicFinal { 

    public static void main(String[] args) { 
     System.out.println(A.s); 
    } 
} 

class A { 
    static { 
     System.out.println("class has been loaded"); 
    } 

    public static final String s = "final"; 

    public static final Integer i = 3; 


} 

Console:

thức

nó gì? Tôi không hiểu tại sao lớp học không được tải, tôi biết các lớp luôn tải ở cuộc gọi đầu tiên. Trường s nằm trong nhóm chuỗi, tôi thấy rằng công cụ sửa đổi cuối cùng là ma thuật. lĩnh vực tôi đã thay đổi:

Nếu tôi xóa sửa đổi lần cuối cùng (public static String s = "final") Tôi sẽ nhận được

Console:

lớp đã được tải

thức

Note i: public static final int i = 3; và hiển thị nó trong conso le. Tôi nhận được giống như trong tình huống Chuỗi. Tại sao?

Trả lời

46

"final"chuỗi ký tự và như vậy là compile-time constant expression. Giá trị của một biến số static final được khởi tạo với biểu thức hằng số biên dịch được mã hóa trực tiếp vào lớp mà tham chiếu đến nó, và không có tham chiếu nào được tạo cho lớp gốc. Do đó việc khởi tạo lớp khởi tạo không xảy ra.

Là một điểm phụ, xin lưu ý sự khác biệt giữa lớp tải và lớp khởi: chỉ xảy ra của khối đó một cách chính xác theo quy định của JLS. Việc tải lớp có thể xảy ra bất cứ lúc nào.

+1

Ok, cảm ơn rất nhiều !! Điều gì về int ?? public static final int i = 3; // wont write class đã được nạp số nguyên tĩnh cuối cùng công cộng i = 3; // write class đã được nạp – idmitriev

+4

Vui lòng đọc định nghĩa biểu thức hằng số biên dịch mà tôi đã liên kết trong câu trả lời của tôi. 'int' là một giá trị nguyên thủy,' String' là trường hợp đặc biệt duy nhất của một giá trị tham chiếu có thể được tham gia vào một biểu thức liên tục và 'Integer' không phải là. –

+0

@marko - Bạn đang nói với tôi rằng lớp A không được tải gì cả? hoặc nó là một trường hợp khởi tạo lười biếng ??? – TheLostMind

3

Đây là nội dung được viết trong Đặc tả ngôn ngữ Java {8.3.2.1 Trình khởi tạo cho biến lớp}. Điều này phải trả lời câu hỏi của bạn

Một sự tinh tế ở đây là, lúc chạy, biến tĩnh cuối cùng và được khởi tạo với giá trị hằng số biên dịch được khởi tạo trước tiên. Điều này cũng áp dụng cho các trường như vậy trong giao diện (§9.3.1). Các biến này là “hằng số” mà sẽ không bao giờ được quan sát để có giá trị ban đầu mặc định của chúng (§4.12.5), thậm chí bằng các chương trình quanh co. Xem §12.4.2 và §13.4.9 để thảo luận thêm.

+0

Có vẻ như bạn đang đề cập đến * Đặc tả Ngôn ngữ Java, Ấn bản thứ ba *. Không có đoạn như vậy trong * Phiên bản Java SE 7 của Java® *. – johnchen902

+0

Có. Đúng vậy. Tôi đã nhìn vào phiên bản cũ nhưng tuyên bố cũng tốt cho JLS 7. Dưới dòng là từ JLS7 Tại thời gian chạy, ruộng tĩnh mà là cuối cùng và được khởi tạo với liên tục biểu thức (§15.28) được khởi động đầu tiên (§12.4.2). Điều này cũng áp dụng cho các trường như vậy trong giao diện (§9.3.1). Các trường này là "hằng số" sẽ không bao giờ được quan sát đến có các giá trị ban đầu mặc định của chúng (§4.12.5), thậm chí bằng các chương trình không rõ ràng (§13.4.9). –

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