2010-12-14 22 views
18

Tôi đang tính lại một số mã được thừa kế, nhưng bị cản trở bởi quyết định thiết kế và không thể tìm ra các thuật ngữ thích hợp cho google này. Người tiền nhiệm của tôi sẽ sử dụng các khối như thế này:Trong Java, tại sao có một khối mã không có từ khóa, chỉ cần dấu ngoặc nhọn

public class ChildClass extends ParentClass { 
    { 
     inheritedVar = "someVal"; 
    } 

    public ChildClass(){ /* constructor exists */ } 
    // rest of code 
} 

Điểm tuyên bố một khối mã không có từ khóa là gì? Nó không hoạt động như một khối tĩnh, tôi không tin. Nó là một thay thế cho thiết lập trong constructor? Điều này sẽ có một số hiệu ứng nếu một nhà máy đã được sử dụng (mà trong trường hợp này nó không)? Tôi tìm thấy một chủ đề liên quan ở đây trên this happening in C nhưng lý do (phạm vi & khai báo biến) dường như không liên quan đến Java.

Bất kỳ ý tưởng hay ý tưởng nào về "lý do" này sẽ được đánh giá cao. Thật dễ dàng để tái yếu tố này, tôi chỉ tò mò vào thời điểm này.

Trả lời

29

Đây là khối khởi tạo. (Liên quan đến khối initializer tĩnh) Xem Khởi tạo Instance thành viên trên trang này:

http://download.oracle.com/javase/tutorial/java/javaOO/initial.html

Đó là một thay thế cho một nhà xây dựng. Bạn có thể sử dụng nó khi cung cấp nhiều, quá trình xây dựng như một cách để chia sẻ mã.

Cá nhân, tuy nhiên, tôi thấy rõ ràng hơn khi có hàm tạo gọi một phương thức khởi tạo được đặt tên thay vì dựa vào khối mã ẩn danh. Mặc dù, trình biên dịch sao chép khối khởi tạo cho tất cả các nhà xây dựng đằng sau hậu trường và bạn có thể tranh luận rằng có một hiệu suất tăng tương tự như inline'ing một khai báo phương thức.

+1

+1 để chỉ ra việc sử dụng chính xác khối này. – birryree

+1

+1: Tôi đồng ý về các phương thức khởi tạo được đặt tên. Tuy nhiên, với điều kiện chỉ có một hàm tạo, toàn bộ điểm của khối này trong cơ sở mã của tôi dường như là vô nghĩa. – Riggy

+0

@Riggy, chắc chắn là không cần thiết. – Mike

-3

Phạm vi. Bất kỳ biến nào được khai báo trong khối sẽ nằm ngoài phạm vi sau khối. Nó rất hữu ích để giữ cho các biến được phạm vi tối thiểu.

Ngoài ra, nếu bạn xác định một lớp bên trong ẩn danh, bạn sử dụng cú pháp này cho hàm tạo.

+0

Không hoàn toàn. Nó sẽ là phạm vi, nó đã được trong một cơ thể phương pháp. Đây là trong lớp cơ thể, bên ngoài của phương pháp. Đọc các câu trả lời khác. –

+0

-1 Đây là câu trả lời sai.Trong trường hợp cho nó là một khối khởi tạo. –

16

Nó được gọi là initializer block.

Initializer khối cho các biến dụ trông giống như khối initializer tĩnh, nhưng không có từ khóa tĩnh:

{ 
     // whatever code is needed for initialization goes here 
    } 

Các khối bản trình biên dịch Java initializer vào mỗi constructor. Do đó, cách tiếp cận này có thể được sử dụng để chia sẻ một khối mã giữa nhiều hàm tạo.

+0

Cả bạn và Mike đều để lại những câu trả lời xuất sắc, cảm ơn cả hai vì đã liên kết. Tôi đã không suy nghĩ về các nhà xây dựng nhiều quá tải, cho rằng các lớp khác nhau tôi đã tìm thấy chỉ có một constructor mỗi. – Riggy

+0

Một nitpick nhỏ - afaik trình biên dịch không sao chép khối khởi tạo, nó chỉ thêm một cuộc gọi từ hàm tạo đến phương thức đặc biệt, đó là những gì mà {} trở thành tệp .class. [Khối khởi tạo tĩnh trở thành phương thức .] –

4

Người tiền nhiệm của bạn vẫn đang học.

Đó là giải thích tốt nhất mà bạn có khả năng nhận được. Có lẽ tại một thời điểm cần phải có mã phân chia như thế này. Khó mà nói ra được. Mã này chắc chắn phải được viết như thế này thay thế:

 
public class ChildClass extends ParentClass { 
    public ChildClass() { 
     inheritedVar = "someVal"; 
    } 
    // rest of code 
} 

Đối với khối khởi tạo, mục đích của nó đã được đưa ra bởi các câu trả lời khác tại đây. Tôi đã ném câu trả lời của tôi vào như một nỗ lực để trả lời "tại sao", mà bạn yêu cầu. Thật không may, đối với câu trả lời thực sự, bạn sẽ phải hỏi người tiền nhiệm của bạn.

+0

Tôi đã chỉ đăng số lượng mã tối thiểu để có được điểm của mình mà không gây gánh nặng cho người đọc SO bằng mã rác. Tôi chỉ đưa vào hàm khởi tạo để có thể thấy rõ rằng một hàm tạo tồn tại trong mã và khối không tên không thay thế hàm tạo. Cảm ơn! – Riggy

+0

Không sao cả. Tôi đã xóa một phần câu trả lời của tôi hỏi về nó. –

+4

Bạn nói đúng rằng đó không phải là mã tốt nhất. Tôi muốn đề nghị người tiền nhiệm đang học. Có rất nhiều nhà phát triển gọi những kẻ ngốc khác, và tất cả những gì nó làm là khiến mọi người che giấu những sai lầm của họ để họ không bị xấu hổ hay tệ hơn, bị sa thải. Tôi muốn thấy "Người tiền nhiệm của bạn vẫn đang học cách viết mã tốt". Tôi đang thực hiện sứ mệnh tạo môi trường an toàn cho các nhà phát triển để tìm hiểu đúng cách để làm mọi thứ và cảm thấy mạnh mẽ rằng StackOverflow phải là một trong số đó - bạn có sẵn sàng trợ giúp và thay đổi ngôn ngữ bạn sử dụng không? – Lunivore

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