2010-08-17 51 views
97

Khi nào các trường tĩnh được khởi tạo? Nếu tôi không bao giờ khởi tạo một lớp, nhưng tôi truy cập một trường tĩnh, có TẤT CẢ các khối tĩnh và các phương thức tĩnh riêng được sử dụng để khởi tạo các trường tĩnh riêng được gọi (theo thứ tự) tại thời điểm đó không?Khi nào khởi tạo lớp tĩnh xảy ra?

Nếu tôi gọi phương thức tĩnh thì sao? Liệu nó cũng chạy tất cả các khối tĩnh? Trước khi phương pháp?

+0

tương tự cho các khối initializer tĩnh: http://stackoverflow.com/questions/ 2007666/in-what-order-do-static-initializer-blocks-in-java-run –

Trả lời

138

khởi tĩnh của một lớp thường xảy ra ngay trước khi lần đầu tiên một trong những sự kiện sau đây xảy ra:

  • một thể hiện của lớp được tạo ra,
  • một phương pháp tĩnh của lớp được gọi,
  • trường tĩnh của lớp được chỉ định,
  • trường tĩnh không cố định được sử dụng hoặc
  • cho một lớp cấp cao nhất, một câu lệnh khẳng định được lồng trong lớp là Thực thi.

Xem JLS 12.4.1.

Nó cũng có thể để buộc một lớp học để khởi tạo (nếu nó chưa được khởi tạo) bằng cách sử dụng Class.forName(fqn, true, classLoader) hoặc các hình thức ngắn Class.forName(fqn)

+0

Cảm ơn bạn vì thông tin bổ sung. –

+5

+1 để cung cấp tham chiếu JLS – Moshe

+4

Cũng lưu ý rằng biểu mẫu ngắn hơn 'Class.forName (className)' cũng buộc khởi tạo vì nó tương đương với 'Class.forName (className, true, currentLoader)'. – user113215

1

Có, tất cả trình khởi chạy tĩnh đều chạy trước khi bạn truy cập vào lớp học lần đầu tiên. Nếu đó là bất kỳ cách nào khác, tôi sẽ gọi nó là một lỗi.

+0

Có nhiều cách để tham khảo một lớp mà không khởi tạo nó. –

11

Trường tĩnh được khởi tạo trong giai đoạn "initialization" của tải lớp (tải, liên kết và khởi tạo) bao gồm khởi tạo tĩnh và khởi tạo các trường tĩnh của nó. Trình khởi tạo tĩnh được thực thi theo thứ tự văn bản như được định nghĩa trong lớp.

xem xét ví dụ:

public class Test { 

    static String sayHello() { 
     return a; 
    } 

    static String b = sayHello(); // a static method is called to assign value to b. 
           // but its a has not been initialized yet. 

    static String a = "hello"; 

    static String c = sayHello(); // assignes "hello" to variable c 

    public static void main(String[] arg) throws Throwable { 
     System.out.println(Test.b); // prints null 
     System.out.println(Test.sayHello()); // prints "hello" 
    } 
} 

Các Test.b in null vì khi sayHello được gọi là trong phạm vi tĩnh, tĩnh biến a không được khởi tạo.

+6

Nói đúng, khởi tạo không phải là "giai đoạn" của quá trình tải lớp. Thật vậy, một số lớp * có thể * được tải nhưng không bao giờ được khởi tạo nếu ứng dụng không thực sự sử dụng chúng. –

+0

@Stephen C Bạn nói đúng, tôi đã sử dụng nó vì thiếu một thuật ngữ tốt hơn, có lẽ tôi sẽ trích dẫn nó. – naikus

+0

@StephenC có nghĩa là trong khi việc nạp lớp diễn ra, nó gán bộ nhớ cho các biến tĩnh (& phương thức) nhưng các biến tĩnh đó không được khởi tạo với các giá trị được cung cấp trong mã? vì ở đây có vẻ như khi b-> sayHello() -> a, 'a' nằm trong bộ nhớ nhưng giá trị cho nó vẫn chưa được gán. –

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