2012-04-22 27 views
7

Tôi đang thực hiện hướng dẫn mã 'tĩnh' của một đồng nghiệp (một sinh viên khác)Thực tiễn tốt nhất của Java - Tuyên bố hàm tạo trước khi biến lớp biến thành một điều xấu?

Với tôi, điều này không có ý nghĩa; đọc từ trên xuống dưới các đối tượng 'thành phần' này được khởi tạo (và sau đó được sử dụng trong hàm tạo) trước khi chúng được khai báo. Tuy nhiên, mã vui vẻ biên dịch và chạy. Đây có phải là hành động xấu không?

Public Class theObject { 

    private static final long aVariable = 123123123123123; 

    public theObject(...){ 

     componentOne = new Component(...); 
     componentTwo = new Component(...); 

     ... 
     ... 
     componentOne.doSomething(...); 
    } 

    private Component componentOne; 
    private Component componentTwo; 
} 
+0

Đây là OOP !!!! (đá .. rơi vào tốt). AFAIK Có một số kiểm tra phong cách cảnh sát có thể làm nổi bật thực tế là các thành viên private được khai báo trước constructor theo sau là khai báo của các thành viên công khai, nhưng tuyên bố đó không có bất kỳ tác động nào trên conpiler không giống như các ngôn ngữ như C – frictionlesspulley

Trả lời

31

Sun Microsystems (nay là thực hiện trên của Oracle) công bố Java Coding Style Guide của nó vào năm 1998, trong đó họ đề nghị một tổ chức cụ thể để khai báo lớp:

  1. tĩnh khai lĩnh vực biến
  2. Instance tờ khai lĩnh vực biến
  3. Trình khởi chạy tĩnh
  4. Khai báo lớp bên trong thành viên tĩnh [*]
  5. Khai báo phương thức tĩnh
  6. Instance initializer
  7. tờ khai constructor Instance
  8. tờ khai viên
  9. Instance bên trong lớp [*]
  10. phương pháp sơ thẩm tuyên bố

Lưu ý rằng điều này đặt tờ khai dữ liệu ở phía trên cùng của tập tin. (An earlier Sun publication from 1997 không bao gồm tất cả mọi thứ trong danh sách trên.) Thứ tự quan trọng duy nhất nằm trong các trường tĩnh và trong các trường thể hiện, và sau đó chỉ khi các trường chứa trình khởi tạo tham chiếu đến các trường khác. Bạn không thể sử dụng một trường trong trình khởi tạo trước khi nó được khởi tạo. Tương tự như vậy, một bộ khởi tạo (mục 3 hoặc 6) không thể thực hiện tham chiếu tới một trường, ngoại trừ mục tiêu của một phép gán. (Xem Java Language Specification, Section 8.3.3, để biết thêm thông tin về các tham chiếu chuyển tiếp đó.) Theo như tôi biết, không có gì khác về thứ tự quan trọng.

[*] Các thuật ngữ trong danh sách trên (đó là nguyên văn từ hướng dẫn 1998) đã quá hạn liên quan đến mục 4 và 8. Cụ thể, từ Java tutorial on nested classes:

ngữ: Các lớp lồng nhau được chia thành hai loại: tĩnh và không tĩnh. Các lớp lồng nhau được khai báo là static được gọi là các lớp lồng nhau tĩnh. Các lớp lồng nhau không tĩnh được gọi là các lớp bên trong.

Trong cách sử dụng hiện đại, không có thứ như "lớp bên trong thành viên tĩnh".

2

Các trật tự trong đó các thành viên của một lớp (phương pháp, thuộc tính) đều tuyên bố là không thích hợp. Theo quy ước, thông thường đầu tiên khai báo tất cả các thuộc tính và hằng số, sau đó là các phương thức. Ví dụ, trong mã của bạn: có thể khởi tạo các thuộc tính trong hàm tạo và sau đó khai báo các thuộc tính, đơn giản vì khi một lớp được biên dịch tất cả khai báo thuộc tính sẽ được tính đến, và sau đó, khi hàm tạo thực tế là được gọi là, các thuộc tính sẽ được tìm thấy. Lưu ý rằng các thuộc tính trong hàm tạo không được truy cập tại thời gian biên dịch, đó là lý do tại sao chúng không tạo ra lỗi; họ chỉ được truy cập vào thời gian chạy.

+0

Thứ tự * có thể * quan trọng 'class X {int a = b + 1; int b = 100} 'không giống với' class Y {int b = 100; int a = b + 1; } '' class X' không nên biên dịch, nhưng không có gì sai với 'class Y' – emory

+0

Như đã nêu trong câu trả lời của tôi, thứ tự _declaration_ của các thuộc tính không quan trọng. Trong ví dụ của bạn, bạn thuộc tính _initializing_, tất nhiên đó là một câu chuyện hoàn toàn khác. –

8

Không có sự đồng thuận thực sự về điều này. Hầu hết mọi người sẽ khai báo các biến lớp ở đầu lớp thực hiện theo sau bởi các phương thức nhưng đó không phải là một yêu cầu. Một số sách như Code Complete đề xuất khai báo các biến càng gần càng tốt như lần sử dụng đầu tiên của chúng. Điều này giúp giảm phạm vi của biến ở mức tối thiểu.

+0

Mã +1 Hoàn thành là phải đọc cho mọi lập trình viên nghiêm túc –

+0

@ 赢 郭 88888888, do đó biến không bị "mất" trong mã. Nếu bạn khai báo mọi biến ở đầu mỗi tệp, bạn có thể không biết nó được sử dụng khi bạn xem lại mã hoặc chỉ đơn giản là làm việc trên nó. Nguyên tắc là: "Tôi sẽ không sử dụng biến này trước khi tôi khai báo hàm này, vậy tại sao tôi lại khai báo nó trước đây?". Cá nhân tôi không thực sự tuân theo quy tắc này nhưng tôi biết một số người làm và nó được đề nghị trong Code Complete. – Chris911

5

Không có chúng không được khởi tạo trước khi thay thế được khai báo. Thứ tự khởi tạo được cố định trong Java và không quan trọng trong đó trong mã mà bạn đặt các khai báo và các nhà xây dựng của mình.

Đối với quy ước, nó thực sự phụ thuộc vào những gì bạn cảm thấy thoải mái. Mặc dù sự thật là quy ước là để khai báo các đệ trình đầu tiên và sau đó các nhà thầu, cách tiếp cận của bạn cũng có giá trị như bất kỳ việc nào khác, miễn là nó không chống lại bản chất hoặc quy định của công ty bạn. Hơn nữa, có nhiều thứ nguy hiểm hơn để đưa vào mã của bạn làm cho nó ít có thể đọc được, chẳng hạn như biến một chữ cái hoặc sử dụng rộng rãi các cấu trúc ít phổ biến hơn (toán tử bậc ba cho các điều kiện phức tạp), ví dụ). Tổ chức mã là một trong những mối quan tâm ít hơn, như bất kỳ IDE phong nha có thể tổ chức lại mã bằng bất kỳ cài đặt nào bạn đặt ở đó.

2

Điều này trái với quy ước thông thường, và (như vậy) nó làm cho mã ít dễ đọc hơn đối với những người mong đợi các quy ước thông thường được tuân theo ... tức là hầu hết các lập trình viên Java.

Mặt khác, nếu mã thực hiện điều này một cách nhất quán và mã tuân theo quy ước mã hóa cục bộ được đồng ý thì người đọc sẽ quen với nó.

Vì vậy, câu trả lời cho câu hỏi "Thực tiễn này có tệ không?" là nó phụ thuộc vào quy ước mã hóa đã đồng ý của bạn và những gì nó nói về điều này.

Nhưng câu trả lời meta là thực hiện đánh giá mã mà không có quy ước mã hóa đồng ý là một ý tưởng thực sự tồi. Nếu không có quy ước mã hóa, không có cơ sở khách quan để xem xét kiểu mã. Bạn có trách nhiệm kết thúc với một kết quả xấu.

2

Đặc tả ngôn ngữ Java chính xác định trong các phần 8.1.1, 8.3.1 và 8.4.3 dòng sau đây mà chúng ta phải sử dụng:

  1. công
  2. bảo vệ
  3. tin
  4. trừu tượng
  5. tĩnh
  6. thức
  7. thoáng
  8. dễ bay hơi
  9. đồng bộ
  10. mẹ đẻ
  11. strictfp

Lệnh này chúng ta phải sử dụng khi chúng ta đang viết code trong Java;)

Link to the Java Language Specification

3

Trình tự khai chung trong java, (tham khảo: Java Coding Style Guide)

 public class DeclarationOrder { 

     // Class (static) variables 
     public static int publicClassVariable; 
     protected static int protectedClassVariable; 
     static int defaultClassVariable; 
     private static int privateClassVariable; 

     // Instance variables 
     public int publicInstanceVariable; 
     protected int protectedInstanceVariable; 
     int defaultInstanceVariable; 
     private int privateInstanceVariable; 

     // Constructors 
     public DeclarationOrder() { 
      // Public Constructor 
     } 
     protected DeclarationOrder(int var) { 
      // Protected Constructor 
     } 
     DeclarationOrder(String var) { 
      // Default Constructor 
     } 
     private DeclarationOrder(Double var) { 
      // private Constructor 
     } 

     // Class (static) Methods 
     public static void publicClassMethod(){} 
     protected static void protectedStaticMethod(){} 
     static void defaultStaticMethod() {} 
     private static void privateStaticMethod(){} 

     // Instance Methods 
     public void publicInstaceMethod() {} 
     protected void protectedInstanceMethod() {} 
     void defaultInstanceMethod() {} 
     private void privateInstanceMethod() {} 
    } 

Trình tự trong mỗi bộ nên được,

  1. Công
  2. Protected
  3. mức trọn gói (không truy cập modifier) ​​
  4. Private
Các vấn đề liên quan