2013-08-07 27 views
6

Các dự án của tôi có một số nhà phát triển yêu thích khối khởi tạo không tĩnh.Cách thay thế cho khối khởi tạo không tĩnh là gì?

các thay thế vấn đề này là gì và Nhược điểm của phương án này là gì? Tôi đoán: khởi tạo các giá trị trong hàm tạo ?

Tại sao chúng ta nên sử dụng khối không khởi tạo? Theo tôi hiểu "khối khởi tạo" được sử dụng để đặt giá trị khi khởi tạo lớp. Là một nhà xây dựng sau đó không đủ?

public class BlockTest { 
    String test = new String(); 

    //Non-static initialization block 
    { 
     test = "testString"; 
    } 
} 

Khối này làm tôi bối rối và dẫn đến giảm khả năng đọc. Cám ơn phản hồi của bạn!

+0

một constructor .. – Ankit

Trả lời

10

Trước hết, không thể khởi tạo kiểm tra thành một chuỗi mới() ở đó, vì khối khởi tạo ngay lập tức gán nó cho thứ gì khác. Dù sao thì ...

Một thay thế được khởi tạo tại tờ khai:

public class BlockTest { 
    String test = "testString"; 
} 

khác là trong các nhà xây dựng:

public class BlockTest { 
    String test; 
    public BlockTest() { 
     test = "testString"; 
    } 
} 

Đó là hai chính, lựa chọn phổ biến.

Có hai cách sử dụng chính cho khối khởi tạo.Đầu tiên là cho các lớp học vô danh mà phải thực hiện một số logic trong quá trình khởi:

new BaseClass() { 
    List<String> strings = new ArrayList<String>(); 
    { 
     strings.add("first"); 
     strings.add("second"); 
    } 
} 

Thứ hai là để khởi tạo phổ biến mà phải xảy ra trước mỗi constructor:

public class MediocreExample { 
    List<String> strings = new ArrayList<String>(); 
    { 
     strings.add("first"); 
     strings.add("second"); 
    } 
    public MediocreExample() { 
     ... 
    } 
    public MediocreExample (int parameter) { 
     ... 
    } 
}   

Tuy nhiên, trong cả hai trường hợp có những lựa chọn thay thế không sử dụng các khối khởi tạo:

new BaseClass() { 
    List<String> strings = createInitialList(); 
    private List<String> createInitialList() { 
     List<String> a = new ArrayList<String>(); 
     a.add("first"); 
     a.add("second"); 
     return a; 
    } 
} 

Và:

public class MediocreExample { 
    List<String> strings; 
    private void initialize() { 
     strings = new List<String>(); 
     strings.add("first"); 
     strings.add("second"); 
    } 
    public MediocreExample() { 
     initialize(); 
     ... 
    } 
    public MediocreExample (int parameter) { 
     initialize(); 
     ... 
    } 
}   

Có nhiều cách để thực hiện những việc này, sử dụng cách phù hợp nhất và cung cấp mã rõ ràng và dễ bảo trì nhất.

+0

+1 để bao gồm các trường hợp xem xét giá trị thay thế. – kiheru

+0

Đúng là nó không có ý nghĩa để khởi tạo chuỗi ở đó, nhưng điều này chỉ dành cho mục đích ví dụ ;-) –

2

khối khởi tạo không có thay thế, trên thực tế nó là một thay thế cho hàm tạo.

public TestClass { 
     TestClass() { 

     } 
    } 

Điều này rất hữu ích trong trường hợp lớp ẩn danh, vì bạn không thể có một nhà xây dựng trong đó, lý do khá thẳng về phía trước, bạn không có tên cho lớp học, bạn không thể có constructor nếu không thì bạn sẽ đặt tên nó là gì.

new MyClass(){ 
    //its an anonymous class, you can't use constructor here 
     { 
     } 
    } 

tuy nhiên bạn có thể khởi tạo inline biến với lời tuyên bố của mình như

public TestClass { 
    String test = "value"; 
} 

nhưng nó không phải là một sự thay thế, bởi vì bạn không thể thực hiện bất kỳ hoạt động (nói số học hoặc chuỗi hoạt động) theo cách này, nhưng bạn có thể thực hiện trong khối khởi tạo

public TestClass { 
     String test = "value"; 
     test = test + " not found"//compiler error 
     { 
     test = test + " not found" // valid 
     } 
    } 
+0

Bạn có thể khởi tạo các lĩnh vực mà họ đang tuyên bố, nếu bạn chỉ cần gán giá trị. –

+1

@JasonC xem chỉnh sửa của tôi – Ankit

+0

Cũng lưu ý rằng trong mọi trường hợp, có cách viết lại mà không sử dụng khối khởi tạo không tĩnh. Không phải là bạn luôn muốn, nó có thể là một cấu trúc rất tiện lợi. Nhưng nó không phải là khá đúng rằng "khối khởi tạo không có thay thế". –

6

Trình biên dịch chèn khối init không tĩnh vào mỗi hàm tạo. Mã cần thiết để khởi tạo các trường cá thể cũng được chèn vào từng hàm tạo. Đây

class Test1 { 
    int x = 1; 
    { 
     x = 2; 
    } 
    Test1() { 
     x = 3; 
    } 
} 

biên dịch vào bytecoode giống như này

class Test1 { 
    int x; 
    Test1() { 
     x = 1; 
     x = 2; 
     x = 3; 
    } 
} 
+0

Điều đó có thể đúng, nhưng bản chất của câu hỏi bao quanh cú pháp và hành vi quan sát được, không phải mã byte tương đương sau biên dịch. 1 để minh họa rõ ràng thứ tự khởi tạo mặc dù (ngay cả khi nó không nhất thiết là mục tiêu của bạn). –

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