2012-12-19 39 views
23

tôi có 2 lớp:Trình khởi chạy tĩnh chạy sau hàm tạo, tại sao?

Class A:

public class A { 
    static B b = new B(); 

    static { 
     System.out.println("A static block"); 
    } 

    public A() { 
     System.out.println("A constructor"); 
    } 
} 

Class B:

public class B { 
    static { 
     System.out.println("B static block"); 
     new A(); 
    } 

    public B() { 
     System.out.println("B constructor"); 
    } 
} 

tôi tạo ra một lớp chính mà chỉ tạo ra một mới:

public class Main { 
    public static void main(String[] args) { 
     new A(); 
    } 
} 

Các sản lượng tôi nhận được là:

B static block 
A constructor 
B constructor 
A static block 
A constructor 

Như bạn có thể thấy, hàm tạo của A được gọi trước bộ khởi tạo tĩnh của nó.

Tôi hiểu rằng nó có liên quan đến sự phụ thuộc chu kỳ mà tôi đã tạo nhưng tôi đã có ấn tượng rằng bộ khởi tạo tĩnh luôn luôn chạy trước hàm tạo.

Lý do cho điều này xảy ra (về mặt kỹ thuật trong triển khai java) là gì?

Bạn có nên tránh các trình khởi tạo tĩnh cùng nhau không?

+0

Ai downvoted xin vui lòng để lại một bình luận –

+2

câu hỏi tốt thực sự +1 .. :) – PermGenError

+0

@AviramSegal một số người là thói quen downvote .. họ không bao giờ đọc toàn bộ câu hỏi, bằng cách đọc nhóm, họ downvote câu hỏi. – Ravi

Trả lời

23
static B b = new B(); 

là trước

static { 
    System.out.println("A static block"); 
} 

Vì vậy, bạn yêu cầu trường hợp B được khởi tạo trước khi bạn in "A static block".

Và khởi tạo lớp B có nghĩa là bạn cần tạo một cá thể A. Vì vậy, không có cách nào cho "Một khối tĩnh" được in trước khi thể hiện A được xây dựng.

Có, khởi tạo tĩnh của A là được khởi chạy trước khi hàm tạo được khởi chạy nhưng ngoài việc bế tắc, sẽ không có giải pháp nào khác cho chuỗi bạn yêu cầu.

Lưu ý các cảnh báo trong the specification:

Bởi vì ngôn ngữ lập trình Java là đa luồng, khởi của một lớp hoặc giao diện đòi hỏi đồng bộ hóa cẩn thận, vì một số chủ đề khác có thể cố gắng để khởi tạo cùng lớp hoặc giao diện cùng một lúc. Cũng có khả năng khởi tạo một lớp hoặc giao diện có thể được yêu cầu đệ quy như một phần của việc khởi tạo của lớp hoặc giao diện đó; ví dụ, một biến khởi tạo trong lớp A có thể gọi một phương thức của một lớp B không liên quan, mà có thể lần lượt gọi một phương thức của lớp A. Việc thực hiện máy ảo Java chịu trách nhiệm chăm sóc đồng bộ hóa và khởi đệ quy bằng cách sử dụng các thủ tục sau [doc tiếp tục với các thủ tục hoàn chỉnh]

Một thực hành tốt nhất, trong Java như trong các ngôn ngữ khác, về cơ bản là tránh các phụ thuộc tuần hoàn vì độ phân giải của chúng có thể rất khó dự đoán.

+1

Tôi sẽ hiểu một lỗi, nhưng tại sao lại cho phép hành vi không phù hợp đó? Ngoài ra, không thể tìm thấy tài liệu cho rằng –

+0

ok, tôi bị mất trong các đặc điểm kỹ thuật, cảm ơn bạn! –

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