2011-10-18 36 views
10

Tôi có một enum với một enum lồng nhau (mà tôi muốn làm cho tư nhân), nhưng khi tôi làm như vậy GWT nói với tôi rằng enum lồng nhau là không nhìn thấy và ném một ngoại lệ.Sử dụng một enum lồng nhau trong GWT-RPC

public enum OuterEnum { 
    A(NestedEnum.X), 
    B(NestedEnum.Y), 
    C(NestedEnum.X); 

    NestedEnum nestedValue; 
    private OuterEnum(NestedEnum nv) { nestedValue = nv; } 

    private enum NestedEnum { 
     X, Y; 
    } 
} 

Nếu tôi xóa công cụ sửa đổi riêng khỏi lồng nhau lồng nhau thì mã hoạt động. Tại sao GWT không cho phép công cụ sửa đổi riêng cho các enums lồng nhau? Có cách giải quyết nào không?

+2

Bạn đã thử làm cho nó tĩnh? –

+0

Điều này thực sự tuyệt vời! JLS (phần 8.9) nói rõ ràng "Các kiểu enum lồng nhau là tĩnh hoàn toàn. Nó được phép khai báo rõ ràng một kiểu enum lồng nhau là tĩnh." Điều đó không áp dụng cho 'enum' s lồng trong 'enum' s hoặc là nó một lỗ hổng nhỏ trong trình biên dịch GWT? –

+0

... và trình biên dịch GWT chỉ sử dụng trình biên dịch Eclipse (ECJ) để phân tích mã nguồn và xây dựng các AST. Vì vậy, trình biên dịch Eclipse có lỗi trong việc không phơi bày enum như là tĩnh, hoặc GWT có lỗi khi không suy ra cờ tĩnh cho một enum lồng nhau (tôi muốn dùng ECJ, nhưng nó thực sự phụ thuộc vào ý định của chúng là gì; có thể là do thiết kế). –

Trả lời

2

Việc xử lý tuần tự hoạt động tốt, ít nhất với ví dụ bạn đã cung cấp. Tất cả các enums một serialized/deserialized theo cách sau (GWT 2.4, 2.3, 2.2):

public static OuterEnum instantiate(SerializationStreamReader streamReader) throws SerializationException { 
      int ordinal = streamReader.readInt(); 
      OuterEnum[] values = OuterEnum.values(); 
      assert (ordinal >= 0 && ordinal < values.length); 
      return values[ordinal]; 
} 

    public static void serialize(SerializationStreamWriter streamWriter, OuterEnum instance) throws SerializationException { 
      assert (instance != null); 
      streamWriter.writeInt(instance.ordinal()); 
} 

Ví dụ: tôi không quan trọng những gì được sử dụng bên trong. Chỉ thứ tự được truyền qua mạng. Nó có nghĩa là có một vấn đề ở một nơi khác, GWT đơn giản là không quan tâm cái gì bên trong enum, bởi vì nó không được truyền qua mạng (enum's nên không thay đổi được không cần chuyển trạng thái của nó). Tôi nghĩ rằng sự cố của bạn có thể giống như sau:

public class OuterClass implements Serializable{ 

    private OuterEnum.NestedEnum nested; 
    private OuterEnum outer; 

    public enum OuterEnum { 
     A(NestedEnum.X), B(NestedEnum.Y), C(NestedEnum.X); 

     NestedEnum nestedValue; 

     private OuterEnum(NestedEnum nv) { 
      nestedValue = nv; 
     } 


     private enum NestedEnum { 
      X, Y; 
     } 
    } 
} 

Ví dụ này rất khác so với phiên bản trước. Giả sử OuterClass được sử dụng trong dịch vụ GWT-RPC. Vì NestedEnum được sử dụng làm trường OuterClass, GWT cần tạo một TypeSerializer cho nó. Nhưng vì TypeSerializer là một lớp riêng biệt, nó không có bất kỳ quyền truy cập nào vào NestedEnum (vì nó là riêng tư). Vì vậy, trình biên dịch không thành công.

Đây là trường hợp duy nhất khi ví dụ của bạn không hoạt động. Có thể có một số lỗi trong một số phiên bản GWT cụ thể, nhưng tôi chắc chắn 100% ví dụ của bạn hoạt động trong gwt 2.2-2.4.

0

Điều này có thể liên quan đến JavaScript. Có thể/có thể xảy ra rằng trong bản dịch sang JavaScript lớp lồng nhau được viết là không lồng nhau. Do đó nếu nó là riêng tư, không có gì khác có quyền truy cập vào nó. Cách giải quyết là không làm cho nó riêng tư, phạm vi mặc định sẽ hoạt động tốt.

+0

Đó là một điểm tốt, tôi đã không nghĩ về điều đó.Đặc biệt là tôi muốn nó là riêng tư ... – luketorjussen

-2

Để trở thành kiểu lớp tham số RPC, nó phải có một hàm tạo rỗng để tuần tự hóa. Vì vậy, tôi nghĩ, nếu bạn thêm

private OuterEnum(){ 
// may be you should give a default value to nestedValue 
} 

Nó sẽ hoạt động!

+0

Vấn đề là với khả năng hiển thị của enum bên trong. Nó có thể tuần tự hóa enum bên ngoài Điều này không trả lời câu hỏi của tôi. – luketorjussen

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