Implementing Generic Interface in Java

后端 未结 7 1980
忘了有多久
忘了有多久 2020-12-24 12:38

I have a Java generics question I was hoping someone could answer. Consider the following code:

public interface Event{}
public class AddressChanged implemen         


        
相关标签:
7条回答
  • 2020-12-24 12:50

    AFAIK you cannot do that, because when compiling the source code in Java these will both boil down to handle(Event), making the method ambiguous.

    The generic information is not available during runtime in Java, in contrast to C#. That is why there it works as you describe.

    You will have to change the method names to make them unique, like handleAddressChanged and handleAddressDiscarded.

    This is indeed one of the weak points of Java generics.

    0 讨论(0)
  • 2020-12-24 12:52

    It isn't allowed because Java erases generic signatures during compilation. The interface method will actually have the signature

    public void handle(Object event);
    

    So you have two choices. Either implement separate Handlers for different events:

    public class AddressChangedHandler implements Handles<AddressChanged>{ /* ... */ }
    public class AddressDiscardedHandler implements Handles<AddressDiscarded>{ /* ... */ }
    

    or implement one handler for all but check the type of the incoming event:

    public void handle(Event e){
      if (e instanceof AddressChanged) {
         handleAdressChanged(e);
      }
      else if (e instanceof AddressDiscareded) {
         handleAdressDiscarded(e);
      }
    }
    
    0 讨论(0)
  • 2020-12-24 12:58

    Going after @Amir Raminfar, you can use visitor pattern

    interface Event{
     void accept(Visitor v);
    }
    interface Visitor {
     void visitAddressChanged(AddressChanged a);
     void visitAddressDiscarded(AddressDiscarded a);
    }
    
    class AddressChanged implements Event{
     @Override
     public void accept(Visitor v) {
      v.visitAddressChanged(this);
     } 
    }
    
    class AddressDiscarded implements Event{
     @Override
     public void accept(Visitor v) {
      v.visitAddressDiscarded(this);
     } 
    }
    
    class AddressHandler implements Visitor {
        void handle(Event e){
           e.accept(this);
         }
        public void visitAddressChanged(AddressChanged e){}
        public void visitAddressDiscarded(AddressDiscarded e){}
    }
    
    0 讨论(0)
  • 2020-12-24 13:01

    Unfortunately not. The usual solution (fat, ugly, fast) is to create one Handles interface (i.e. HandlesAddressChange, HandlesAddressDiscarded) and give each of them a different method (handleAddressChange(...), handleAddressDiscarded()).

    That way, the Java runtime can tell them apart.

    Or you can use anonymous classes.

    0 讨论(0)
  • 2020-12-24 13:04

    No, because different "concrete" generic types in Java compile to the same type. The actual interface your object will implement is:

    public interface Handles {
        public void handle(Event event);
    }
    

    And, obviously, you can't have two different methods with an identical signature...

    0 讨论(0)
  • 2020-12-24 13:11

    You can't do that in Java. You can only implement one concrete realization of the same generic interface. I would do this instead:

    public class AddressHandler implements Handles<Event>{
        public void handle(Event e){
          if(e instanceof AddressDiscarded){
             handleDiscarded(e);
          } else if(e instanceof AddressChanged){
             handleChanged(e);
          }
        }
        public void handleDiscarded(AddressDiscarded e){}
        public void handleChanged(AddressChanged e){}
    }
    
    0 讨论(0)
提交回复
热议问题