Vấn đề là rằng các biến phương pháp địa phương từ các loại kèm theo là thực sự sao chép với các trường hợp lớp nặc danh (điều này là bởi vì vấn đề kích hoạt khung hình, nhưng tôi sẽ không đi sâu hơn vào chi tiết vì điều này không thực sự liên quan đến câu hỏi), đó là lý do tại sao chúng cần phải là cuối cùng, bởi vì biến trong thể hiện kiểu lồng nhau không giống nhau nữa.
Vì vậy, đây là ví dụ đầu tiên:
void foo() {
int a = 3;
new Runnable() {
@Override
public void run() {
a += 3;
}
};
}
này không biên dịch, bởi vì bạn không có thể tham khảo một biến phi chính thức trong một phương pháp lớp vô danh. Khi bạn thêm công cụ sửa đổi cuối cùng vào khai báo a
, giá trị của a
sẽ được sao chép vào phiên bản đã tạo của lớp ẩn danh mà bạn đã xác định. Tuy nhiên, bạn sẽ không được phép thay đổi giá trị a
, bởi vì các thay đổi sẽ không được hiển thị cho phương thức mà a
được khai báo.
Tuy nhiên, các lớp học vô danh không phải là tĩnh, có nghĩa là, họ có một tham chiếu đến dụ kèm theo (trừ trường hợp phương pháp mà chúng được khai báo là static) mà bạn có thể sử dụng để sửa đổi các biến của dụ kèm theo:
int a = 3;
void foo() {
new Runnable() {
@Override
public void run() {
a += 3;
}
};
}
Ví dụ này biên dịch và nó sẽ tăng a
3 mỗi lần phương pháp run()
của cá thể lớp ẩn danh 'được gọi. (Trong ví dụ này, nó không bao giờ được gọi, nhưng nó chỉ là một ví dụ.)
Vì vậy, để tóm tắt, bạn cần chuyển đổi biến seatno
từ biến phương thức cục bộ sang biến mẫu của kiểu bao.Hoặc, nếu chưa, bạn cần loại bỏ công cụ sửa đổi cuối cùng vì các biến cuối cùng chỉ có thể được gán một lần.
Cập nhật: Trong Java 8, khái niệm về hiệu quả thức biến được giới thiệu (xem Java Language Specification). Tuy nhiên, trong ví dụ đầu tiên của bài đăng này, biến số a
được gán nhiều lần, điều này ngăn không cho nó có hiệu lực cuối cùng. Điều này có nghĩa rằng ví dụ này vẫn không biên dịch với Java 8. (Lỗi biên dịch là "Biến cục bộ được xác định trong phạm vi bao quanh phải là cuối cùng hoặc hiệu quả cuối cùng")
biến 'seatno' của bạn có từ khóa cuối cùng trong đó. –