2009-02-24 38 views
10

Đường cú pháp được cung cấp bởi cơ sở enum của Java đôi khi có thể hơi khó hiểu. Hãy xem xét ví dụ này, mà không biên dịch:Ngữ cảnh tĩnh trong định nghĩa enum

public enum TestEnum { 

    FOO("foo") { 
     public void foo() { 
      helper(); // <- compiler error 
     } 
    }; 

    String name; 
    TestEnum(String name) { 
     this.name = name; 
    } 

    public abstract void foo(); 

    private void helper(){ 
     // do stuff (using this.name, so must not be static) 
    } 
} 

bất cứ ai có thể giải thích lý do tại sao các trình biên dịch nói

Non-static method 'helper()' không thể được tham chiếu từ một bối cảnh tĩnh

Làm thế nào chính xác là bối cảnh này tĩnh?

Bạn có thể làm cho điều này biên dịch bằng cách thay đổi các cuộc gọi đến this.helper() (đây là một trong những điểm khó hiểu: nếu chúng ta thực sự đang ở trong một "bối cảnh tĩnh" như trình biên dịch cho thấy, làm thế nào có thể "this" làm việc) hoặc bằng cách tăng mức hiển thị của helper() lên mức mặc định. Bạn thích cái nào? Ngoài ra, vui lòng đề xuất tiêu đề câu hỏi hay hơn :-)

Chỉnh sửa: Tôi tìm thấy some discussion about this - nhưng không có câu trả lời thực. Đồng nghiệp của tôi nghĩ rằng thực tế rằng this.helper() hoạt động thực sự là một lỗi trình biên dịch. Và thực sự với các phiên bản Java mới hơn có vẻ như không phải để hoạt động (mặc dù super.helper() có): "không thể tìm thấy biểu tượng trợ giúp()". (Mặc dù có điều gì đó kỳ lạ xảy ra: sau khi thử với các phiên bản Java khác nhau, tôi không thể nhận được this.helper() để biên dịch lại với bất kỳ ...)

Trả lời

0

Có một số article có vấn đề này. Có lẽ bạn vẫn có thể trích xuất một số thông tin hữu ích.

EDIT: Có vẻ là một vấn đề hơi khác với bạn. Tôi vẫn không hiểu hành vi của ví dụ của bạn, mà tôi cũng thấy ở đây.

3

Một cái gì đó như thế này được đề cập trong sách Puzzlers Java. IIRC, bối cảnh lớp bên ngoài luôn được xem xét trước lớp siêu. Trong trường hợp này helper được tìm thấy. Nhưng chúng tôi đang xây dựng giá trị theo ngữ cảnh tĩnh (có hiệu quả là private static final trước FOO). Do đó lỗi.

Hãy thử super.helper();.

+0

Tôi có sách; bạn có nghĩa là câu đố nào? (Tôi không thể tìm thấy nó một cách nhanh chóng.) – Jonik

+0

Cả hai bản sao của cuốn sách của tôi được đóng gói trong hộp ở đâu đó, vì vậy tôi không có ý tưởng. –

2

Nếu tôi dịch enum của bạn vào cấu trúc lớp của nó sẽ xem xét khoảng như thế này:

public abstract class TestEnum { 

    public static final TestEnum FOO = new FOO("foo") { 
    public void foo() { 
     helper(); // <- compiler error 
    } 
}; 

    String name; 
    TestEnum(String name) { 
     this.name = name; 
    } 

    public abstract void foo(); 

    private void helper(){ 
    // do stuff (using this.name, so must not be static) 
    } 

}

Các FOO dụ là một lớp anynomous kéo dài TestEnum. Đó là lý do tại sao tôi tin rằng bạn không thể truy cập helper(), bởi vì nó là riêng tư. Vì vậy, this.helper() có lẽ không nên hoạt động. Tôi không chắc tại sao super.helper() lại hoạt động, nhưng có lẽ enum cho phép bạn truy cập riêng tới cha mẹ.

Đối với lỗi ngữ cảnh tĩnh, tôi đồng ý với thông báo lỗi có vẻ không hợp lý.

+0

Nitpick: với "new FOO" bạn có nghĩa là "new TestEnum" không? – Jonik

+0

vâng bắt được điều đó .. cảm ơn – richs

8

Thông báo lỗi gây hiểu nhầm, chỉ cần bảo vệ helper và nó sẽ hoạt động.

protected void helper(){ 
    // can be called from subclasses (such as FOO) since it is not private 
} 
1

Bạn có thể nghĩ về từng hằng số enum làm trường hợp duy nhất của phân lớp phụ của lớp enum.Cũng giống như với các lớp "thông thường", enum "sub-classes" không thể truy cập các thành viên riêng của enum "super-class". (Tôi không thể tái tạo "này." Công việc xung quanh mà bạn đề cập đến.)

Một giải pháp hợp lý là để thay đổi việc tiếp cận phương pháp từ tin-được bảo vệ để cung cấp cho truy cập vào các enum liên tục " các lớp con. "

Đề xuất tiêu đề câu hỏi hay hơn: "Phương pháp enum riêng tư của Java?" hoặc chỉ "Phương thức enum riêng" (để thẻ Java xử lý Java-ness)

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