2012-05-10 24 views
16

Nếu một tham chiếu đối tượng được chuyển đến một phương thức, có thể đặt đối tượng "Chỉ Đọc" cho phương thức không?Có thể tạo một đối tượng "Chỉ Đọc" cho một phương thức

+5

có một tài nguyên cũ nhưng vẫn tốt: http://www.cs.uwm.edu/~boyland/papers/readonly-talk.pdf –

+0

lưu trữ tham chiếu đến đối tượng, sao chép nó và so sánh theo thời gian nếu không có gì thay đổi? –

Trả lời

15

Không nói đúng. Đó là, một tham chiếu có thể biến đổi một đối tượng không thể được biến thành một tham chiếu mà không thể biến đổi một đối tượng. Ngoài ra, không có cách nào để thể hiện rằng một loại không thay đổi hoặc có thể thay đổi được, ngoài việc sử dụng các quy ước.

Tính năng duy nhất đảm bảo một số hình thức bất biến sẽ là các trường final - khi đã viết chúng không thể sửa đổi được.

Điều đó nói rằng, có nhiều cách để thiết kế các lớp học để đột biến không mong muốn được ngăn chặn. Dưới đây là một số kỹ thuật:

  • Defensive Copying. Vượt qua một bản sao của đối tượng, để nếu nó bị đột biến, nó không phá vỡ các bất biến nội tại của bạn.

  • Sử dụng các công cụ sửa đổi truy cập và/hoặc giao diện để hiển thị chỉ các phương pháp chỉ đọc. Bạn có thể sử dụng công cụ sửa đổi truy cập (public/private/protected), có thể được kết hợp với giao diện để chỉ một số phương thức nhất định hiển thị với đối tượng khác. Nếu các phương pháp tiếp xúc là bản chất chỉ đọc, bạn sẽ an toàn.

  • Làm cho đối tượng của bạn không thay đổi theo mặc định. Bất kỳ thao tác nào trên đối tượng đều trả về một bản sao của đối tượng.

Ngoài ra, lưu ý rằng API trong SDK đôi khi có phương thức trả lại phiên bản không thể thay đổi của một đối tượng, ví dụ: Collections.unmodifiableList. Một nỗ lực để thay đổi một danh sách bất biến sẽ ném một ngoại lệ. Điều này không thực thi bất biến tĩnh (tại thời gian biên dịch với hệ thống kiểu tĩnh), nhưng là một cách rẻ tiền và hiệu quả để thực thi nó một cách năng động (vào thời gian chạy).

Đã có nhiều đề xuất nghiên cứu về phần mở rộng Java để kiểm soát tốt hơn tính năng răng cưa và khả năng truy cập.Ví dụ: thêm từ khóa readonly. Không ai trong số họ là xa như tôi biết kế hoạch để đưa vào phiên bản tương lai của Java. Bạn có thể có một cái nhìn tại các gợi ý nếu bạn quan tâm:

Khung kiểm tra rất thú vị. Trong khung kiểm tra, xem xét bộ kiểm tra loại vũ trụ chung, trình kiểm tra bất biến IGJ và trình kiểm tra bất biến Javari. Khung làm việc bằng cách sử dụng chú thích, vì vậy nó không phải là xâm nhập.

+0

pdf chỉ đọc bị thối liên kết. – flup

3

No. Nhưng bạn có thể cố gắng sao chép đối tượng trước khi truyền, vì vậy mọi thay đổi được thực hiện bởi phương pháp sẽ không ảnh hưởng đến đối tượng ban đầu.

6

Không, không phải không trang trí, ghép, nhân bản, v.v.

6

Không có cơ chế chung cho điều đó. Bạn sẽ cần phải viết mã trường hợp đặc biệt để đạt được nó, như viết một wrapper không thay đổi (xem Collections.unmodifiableList).

1

Bạn có thể xác định tất cả các tham số của đối tượng là final nhưng điều đó làm cho đối tượng chỉ đọc cho tất cả mọi người.

3

Bạn có thể đạt được một điều tương tự như trong hầu hết các trường hợp bằng cách nhân bản Object là tuyên bố đầu tiên của phương pháp, như thế này ...

public void readOnlyMethod(Object test){ 
    test = test.clone(); 
    // other code here 
} 

Vì vậy, nếu bạn gọi readOnlyMethod() và vượt qua trong bất kỳ Object, một bản sao của Object sẽ được thực hiện. Bản sao sử dụng cùng tên với tham số của phương thức, vì vậy không có nguy cơ vô tình thay đổi Object gốc.

+1

Điều này yêu cầu đối tượng thực sự thực hiện 'clone' đúng cách và vì đây là API có chức năng chỉnh sửa, các lớp hiện đại hiếm khi bận tâm với nó. –

+0

Chính xác. Tuy nhiên, tôi hy vọng rằng hầu hết các lớp Java cốt lõi nên triển khai thực hiện 'clone()' đúng cách, vì vậy điều này sẽ bao gồm * hầu hết * các tình huống. Nó có lẽ gần như là bạn sẽ nhận được một tham số chỉ đọc – wattostudios

+1

Làm thế nào về 'Collections.unmodifiableList' - đó là từ API lõi (không nhân bản). –

0

Tùy thuộc vào nơi bạn muốn quy tắc được thực thi. Nếu bạn đang làm việc cộng tác trên một dự án, hãy sử dụng final với nhận xét cho người tiếp theo họ không có ý định sửa đổi giá trị này. Nếu không, bạn sẽ không chỉ cần viết phương thức để không phải chạm vào đối tượng?

public static void main(String[] args) { 
    cantTouchThis("Cant touch this"); 
} 

/** 
* 
* @param value - break it down 
*/ 
public static void cantTouchThis(final String value) { 
    System.out.println("Value: " + value); 
    value = "Nah nah nah nah"; //Compile time error 
} 

Vì vậy, cụ thể cho phương pháp này, giá trị sẽ không bao giờ được ghi vào và được thực thi tại thời gian biên dịch làm cho giải pháp cực kỳ mạnh mẽ. Bên ngoài phạm vi của phương pháp này, đối tượng vẫn không thay đổi gì mà không phải tạo bất kỳ loại trình bao bọc nào.

0
private boolean isExecuteWriteQueue = false; 
public boolean isWriting(){ 
    final boolean b = isExecuteWriteQueue; 
    return b; 
} 
1

làm cho nó triển khai giao diện chỉ đọc các phương thức (không có phương thức setter) cho bản sao đối tượng (bản sao chỉ đường) và trả về phiên bản giao diện chỉ đọc thay vì trả về phiên bản một đối tượng chính nó

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