2012-04-15 27 views
5

Vì vậy, tôi có giao diện nàyLoại Erasure xé đầu xấu xí của nó, làm thế nào để vượt qua?

public interface EventHandler<E extends EventObject> 
{ 
    public void handleEvent(E event); 
} 

và tôi muốn lấy được lớp cho nó có thể xử lý các sự kiện, như vậy:

public class WorkingHandler implements EventHandler<MouseEvent> 
{ 
    public void handleEvent(MouseEvent event) 
    { 
     //handle event 
    } 
} 

Ví dụ ở trên hoạt động tốt. Nhưng trình biên dịch sẽ không cho phép tôi thực hiện EventHandler nhiều lần, do Loại bỏ khó chịu cực kỳ bực bội.

public class NotWorkingHandler implements EventHandler<MouseEvent>, EventHandler<KeyEvent> 
{ 
    public void handleEvent(MouseEvent event) 
    { 
     //handle mouse event 
    } 

    public void handleEvent(KeyEvent event) 
    { 
     //handle key event 
    } 
} 

Một số câu hỏi ...

  1. Tại sao Java không cho phép Loại Erasure? IIRC nó là cái gì để làm với việc tương thích với các phiên bản trước của Java, đúng không?

EDIT: Ý tôi là tại sao Java có Loại Erasure (đã có nó theo cách khác xung quanh)

  1. Có bất kỳ loại "mod"/"mở rộng" (vì thiếu một từ tốt hơn) hoặc các ngôn ngữ lập trình cho phép tôi có được xung quanh Loại Erasure? Vì tôi không sử dụng các phiên bản Java cũ hơn nên tôi không quan tâm đến mã của mình đang tương thích với mã cũ hơn.

  2. Có cách giải quyết nào không, trong ngôn ngữ Java, mà tôi có thể sử dụng để xử lý Loại xóa?

  3. Nếu không, một số cách thay thế để mã xử lý sự kiện trong chương trình của tôi giúp trình biên dịch hài lòng là gì?

+4

-- không có ý nghĩa. Java không cho phép xóa bỏ loại - thực tế nó thực hiện xóa bỏ kiểu. – emory

+0

"Có bất kỳ loại" mod "/" tiện ích mở rộng "nào (vì thiếu từ tốt hơn) hoặc ngôn ngữ lập trình cho phép tôi sử dụng Loại xóa không?" - Có, nhiều ngôn ngữ không có loại tẩy xoá. – emory

+1

Bạn đang tìm kiếm C# –

Trả lời

1

Tôi không chắc rằng hiểu biết của bạn Loại Erasure trong Java là đúng. Như được giải thích here, loại của lớp chung của bạn bị mất khi chạy.

Đáp lại câu hỏi của bạn:

  1. Tôi nghĩ rằng bạn là đúng rằng Java thực hiện loại tẩy xoá để cho phép khả năng tương thích với các phiên bản trước của langauge.
  2. Không, tôi không nghĩ rằng có một "mod".
  3. Không có cách giải quyết nào (loại được loại bỏ tại thời gian biên dịch), nhưng bạn có thể sử dụng sự phản chiếu.
  4. Xem bên dưới.

Tôi nghĩ rằng một giải pháp đơn giản sẽ được để một cái gì đó như thế này: "Tại sao Java không cho phép Loại Erase"

public class WorkingHandler implements EventHandler<EventObject> 
{ 
    public void handleEvent(EventObject event) 
    { 
     // handle event 
     if (event instanceof MouseEvent) 
      handleMouseEvent((MouseEvent) event); 
     ... 
    } 

    ... 

    private void handleMouseEvent(MouseEvent event) 
    { 
     // handle mice 
    } 
} 
2

Loại Xóa là tốt vì có nghĩa là JVM không cần biết bất kỳ điều gì về loại Chung. Điều này cũng có nghĩa là không có tác động hiệu suất từ ​​việc sử dụng các loại Generic.

Ngoài ra, khái niệm của bạn về sự cần thiết phải duy trì tính tương thích nhị phân là vị trí trên (như được chỉ ra trong Type Erasure tutorial). Kiểu xóa cho phép mã được viết trước khi Java cho phép Các kiểu generic tương thích liền mạch với mã Java được viết bằng Generics.

Làm thế nào về việc chỉ cần thực hiện hai trình xử lý và đính kèm cả hai?

public class KeyHandler implements EventHandler<KeyEvent> 
{ 
    public void handleEvent(KeyEvent event) 
    { 
     //handle key event 
    } 
} 

public class MouseHandler implements EventHandler<MouseEvent> 
{ 
    public void handleEvent(MouseEvent event) 
    { 
     //handle mouse event 
    } 
} 
5

Một tùy chọn là sử dụng GuavaEventBus để đăng sự kiện cho người đăng ký. Nó được thiết kế đặc biệt để giải quyết vấn đề bạn đang phải đối mặt, trong số những thứ khác.

Với nó, bạn không cần phải thực hiện bất kỳ giao diện ... chỉ cần cung cấp hai @Subscribe phương pháp như thế này:

@Subscribe 
public void handleKeyEvent(KeyEvent event) { ... } 

@Subscribe 
public void handleMouseEvent(MouseEvent event) { ... } 

Một số tài liệu bổ sung vào nó có sẵn trên Ổi wiki.

1
  1. Có, loại tẩy xóa được thực hiện sao cho thông số kỹ thuật của JVM không phải thay đổi để chạy phiên bản mới (một triển khai generics).

  2. Như đã chỉ ra nhiều ngôn ngữ khác không loại bỏ xóa. Nếu bạn đang tìm kiếm trong Java, có thể, nhưng tôi không chắc chắn - không nó sẽ không hoạt động trên các JVM tiêu chuẩn chính xác vì 1.

  3. Bạn có thể làm một xử lý sự kiện chung:

.

public class GenericHandler implements EventHandler<EventObject> 
{ 
    public void handleEvent(EventObject event) 
    { 
    if (event instanceof MouseEvent) { 
     MouseEvent mouseEvent = (MouseEvent) event; 
     //handle mouse event 
    } else if (event instanceof KeyboardEvent) { 
     KeyboardEvent keyboardEvent = (KeyboardEvent) event; 
     //handle keyboard event 
    } 
    } 
} 

Không phải là thanh lịch nhất, nhưng hoạt động :)

+2

Bạn có thể loại bỏ chuỗi "if instanceof ..." bằng cách triển khai mẫu thiết kế Visitor và công văn kép. –

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