2011-01-24 28 views
9

thể trùng lặp:
Cannot refer to a non-final variable inside an inner class defined in a different methodTại sao các biến cục bộ của tôi cuối cùng có thể truy cập được từ lớp ẩn danh?

lý do đằng sau sự cai trị của việc có các biến địa phương khai báo là cuối cùng để truy cập chúng từ lớp ẩn danh là gì?

+0

Bản sao của http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different (nhưng không còn đóng phiếu) – skaffman

Trả lời

6

Khi bạn truy cập biến số final từ một lớp ẩn danh, trình biên dịch sẽ sao chép bí mật giá trị của chúng vào một biến thành viên của lớp ẩn danh. ví dụ:

Runnable foo() { 
    final int x = 42; 
    return new Runnable() { 
    void run() { 
     System.out.writeln(x); 
    } 
    }; 
} 

trở thành:

// the actual name is generally illegal in normal java syntax 
class internal_Runnable implements Runnable { 
    final int x; 
    internal_Runnable(int _x) { x = _x; } 
    void run() { 
    System.out.writeln(x); 
    } 
} 

void foo() { 
    final x = 42; 
    return new internal_Runnable(x); 
} 

Nếu biến là không chính thức và được phép thay đổi, giá trị cache trong trường hợp lớp nặc danh có thể đi ra ngoài đồng bộ. Điều này có thể tránh được bằng cách sử dụng một bao đóng - đó là, một đối tượng giữ các giá trị của tất cả các biến cục bộ, cả hàm gốc và truy cập cá thể lớp ẩn danh mới. .NET uses closures, for example. Tuy nhiên, điều này có thể gây ra một hit hiệu suất, và có lẽ vì lý do đó, các nhà thiết kế ngôn ngữ Java quyết định không hỗ trợ đóng cửa đầy đủ.

0

Đó là vì đối tượng bên trong ẩn danh có thể tồn tại lâu hơn ngữ cảnh của nó, nếu nó đề cập đến các biến không phải là final, sau đó sẽ nói với những thứ không tồn tại nữa.

8

... khi một đối tượng của lớp vô danh được khởi tạo, bản sao của các biến địa phương thức và các thông số phương pháp được gọi bằng phương pháp của đối tượng được lưu trữ như biến dụ trong đối tượng. Các phương thức trong đối tượng của lớp vô danh thực sự truy cập vào các biến đối tượng ẩn ẩn đó.

Do đó, các địa phương biến và phương pháp thông số truy cập bởi các phương pháp của lớp địa phương phải được tuyên bố cuối cùng để ngăn chặn giá trị của họ từ việc thay đổi sau khi đối tượng được khởi tạo.

Từ here.

1

Lớp ẩn danh là một lớp riêng biệt. Nó không có quyền truy cập vào luồng điều khiển bên trong phương thức của bạn. Nếu bạn gán lại biến trong lớp ẩn danh, bạn sẽ chỉ gán lại bản sao biến của lớp ẩn danh đó. Điều đó sẽ rất dễ bị lỗi, và do đó lựa chọn thiết kế đã được thực hiện để làm cho nó một lỗi.

Nếu bạn muốn giải quyết vấn đề đó, hãy sử dụng số AtomicReference.

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