2012-04-04 13 views
5

Tôi đang đọc "Thiết kế API thực tế" và tìm đoạn sau:Sử dụng getter/setter ngoài lĩnh vực công cộng để tương thích nhị phân?

"Lý do khác để thích phương thức trên các trường có thể được tìm thấy trong đặc tả JVM. Bạn được phép di chuyển phương thức từ lớp này sang lớp khác Vì vậy, một phương thức ban đầu được giới thiệu là Dimension javax.swing.JComponent getPreferredSize (Dimension d) có thể bị xóa trong một phiên bản mới và được chuyển đến Dimension java.awt.Component.getPreferredSize (Dimension d) Một sự thay đổi như thế này thực sự đã xảy ra trong JDK 1.2, và điều này có thể được thực hiện chỉ vì trường đã được đóng gói bởi một phương thức, một hoạt động như thế này không được phép cho các trường. được định nghĩa trong một lớp, nó phải ở đó cho foreve r để duy trì tính tương thích nhị phân, đó là một lý do khác để giữ cho các trường riêng tư "

vì tôi đồng ý sử dụng getter/setter là cách tốt hơn. Nhưng tôi không hiểu tại sao việc chuyển trường công khai sang lớp cha sẽ phá vỡ tính tương thích nhị phân? Bạn vẫn có thể truy cập vào trường đó thông qua lớp con miễn là nó được công khai trong phụ huynh.

Trả lời

3

Khi một lĩnh vực được định nghĩa trong một lớp học, nó phải ở lại đó mãi mãi để duy trì khả năng tương thích nhị phân

Đó sẽ là rất đáng ngạc nhiên:

Java Language Specification, Java SE 7 phiên bản , defines tên nhị phân của biểu thức truy cập trường không đủ điều kiện như sau:

Cho biểu thức pháp lý biểu thị quyền truy cập trường một lớp C, tham chiếu một trường không liên tục (§13.4.9) có tên là f được khai báo trong một lớp (hoặc có thể khác biệt) D, chúng ta xác định loại vòng loại tham chiếu trường như sau:

  • Nếu biểu thức có dạng Primary.f sau đó:
    • Nếu loại thời gian biên dịch chính là loại giao nhau (§4.9) V1 & ... & Vn, thì loại vòng loại tham chiếu là V1.
    • Nếu không, loại thời gian biên dịch của Chính là loại đủ điều kiện của tham chiếu.

(Các Đặc điểm kỹ thuật ngôn ngữ cho Java 1.5 uses chính xác từ ngữ tương tự)

Tức là tên nhị phân của biểu thức truy cập trường không tham chiếu đến loại khai báo trường, chỉ cho loại biểu thức chính mà chúng tôi sử dụng để truy cập trường đó siêu lớp của loại đó khai báo trường, trình biên dịch là yêu cầu để phát ra trường hợp cùng một tham chiếu trường vào tệp lớp.

Thật vậy, khi tôi cố gắng chỉ là bây giờ phát triển từ

package p; 

public class Super { 

} 

package p; 

public class Sub extends Super { 
    public String message; 

    @Override 
    public String toString() { 
     return message; 
    } 
} 

để

package p; 

public class Super { 
    public String message; 
} 

package p; 

public class Sub extends Super { 
    @Override 
    public String toString() { 
     return message; 
    } 
} 

mà không cần biên dịch lại

package p; 

public class Main { 
    public static void main(String[] args) { 
     Sub sub = new Sub(); 
     sub.message = "hello"; 
     System.out.println(sub); 
     System.out.println(sub.message); 
    } 
} 

tôi vẫn nhận được đầu ra của

hello 
hello 

, không phải là LinkageError.

Để kết luận, xác nhận quyền sở hữu đó không đúng đối với Java 7. Điều này có thể đúng với JDK 1.4 hoặc cũ hơn, được tuyên bố là kết thúc vòng đời hơn 5 năm trước. Dù bằng cách nào, có lẽ bạn nên sử dụng một cuốn sách tốt hơn/gần đây hơn?

+0

Đây chỉ là điều tôi có thể đoán được. Có lẽ ở thời điểm rất cũ, nó là. –

0

Nếu tôi nhớ chính xác cuốn sách giải thích điều này, nhưng hiện tại tôi chưa có sách. Tôi nghĩ đó là sự khác biệt tinh tế giữa ngôn ngữ Java và định dạng tệp lớp (được sử dụng bởi các ngôn ngữ khác ngoài Java).

Kiểm tra sách trước hoặc sau một lát. Hỏi xem bạn có thêm câu hỏi về phần đó không.

+0

Tôi thực sự đăng câu hỏi sau khi kết thúc chương đó. Tôi không thấy lời giải thích nào cả. Mặc dù có một số nội dung về JVM hotspot, tôi không nghĩ rằng phần đó trả lời câu hỏi của tôi –