Tôi muốn tạo một enum
trong đó mỗi hằng số có Map
được liên kết với nó. Tôi thực hiện điều này bằng cách cho mỗi liên tục khởi tạo một thể hiện, như vậy:Tại sao tính toán này được biên dịch?
import java.util.HashMap;
import java.util.Map;
public enum Derp {
FOO {{
mMap.put("bar", 1);
}};
// cannot be private
protected final Map<String, Integer> mMap = new HashMap<>();
}
Tôi thấy rằng nếu mMap
là private
, nó không thể được tham chiếu trong initializer dụ. Lỗi là Cannot make a static reference to the non-static field mMap
. Trước khi lý do cho điều này xảy ra với tôi, tôi tham khảo ý kiến JLS §8.9.2, mà nói trong phần:
Đó là một lỗi thời gian biên dịch cho các nhà thầu, khối dụ initializer, hoặc dụ biểu thức khởi tạo biến của một enum liên tục
e
để tham khảoe
hoặc đến một hằng số enum cùng loại được khai báo ở bên phảie
.
Không phải tôi phá vỡ quy tắc này bằng cách mặc nhiên tham khảo FOO
trong intializer dụ riêng FOO
's? Làm thế nào để biên dịch? Nó không chỉ biên dịch, mà còn hoạt động chính xác khi chạy.
(Nó xảy ra với tôi rằng mMap
không thể private
vì tôi ngầm tạo ra một lớp con nặc danh mà không thể tham chiếu đến một lĩnh vực private
trong lớp cha của nó. Đó là một chút kỳ lạ trong bản thân kể từ enums đang ngầm final
...)
"enums đang ngầm 'final'" - [không hoàn toàn] (http://ideone.com/3bi0U1). Java cần tạo các lớp con ngầm mỗi trường hợp mỗi lần bạn làm điều với các dấu ngoặc bên cạnh hằng số enum, vì vậy nếu bạn làm điều đó, lớp enum không phải là cuối cùng. Tuy nhiên, bạn vẫn không thể khai báo các lớp con của riêng mình. – user2357112
Đủ điều kiện cuộc gọi như 'super.mMap.put (...);'. Lý do đằng sau điều này chỉ là một đặc điểm kỹ thuật kỳ lạ. – Radiodef
@Radiodef Tôi không tin rằng đây là bản sao. Tôi nghĩ rằng tấm áp phích này hỏi hai câu hỏi mà không được hỏi trong bài đăng liên kết: (1) tại sao nó hợp pháp nếu anh ta sử dụng 'protected' và (2) tại sao không phải là tham chiếu tự ngầm tiềm ẩn. Tôi nhìn qua các câu trả lời ở đó, và họ không trả lời câu hỏi cho sự hài lòng của tôi. – ajb