Returning restricted Java shared objects from a method

I am familiar with Oracle tutorials and questions such as How to make a method a generic return type? but still I am unable to return the shared objects from the Java method.

A quick example: I have a network hierarchy Packetand an Handlers hierarchy parameterized to Packetwhich they process. In the end, I have a registry Handlerthat includes a method that returns me the correct handler for this package.

I would like to realize all this, ideally without warning, for manual suppression.

class Packet {}
class ThisPacket extends Packet {}
class ThatPacket extends Packet {}

interface PacketHandler<P extends Packet> {
    boolean handle(P p);
}

class ThisPacketHandler extends PacketHandler<ThisPacket> {
    boolean handle(ThisPacket p);
}

class ThatPacketHandler extends PacketHandler<ThatPacket> {
    boolean handle(ThatPacket p);
}

, , , , , .

i) :

class HandlersRegistry {
    static <<RETURN TYPE>> getHandler(Packet p) {
        if (p instanceof ThisPacket) return new ThisPacketHandler();
        if (p instanceof ThatPacket) return new ThatPacketHandler();
        return null;
    }
}

<<RETURN TYPE>> OPTIONS (I tried):
    // Raw-type Warning:
    A. PacketHandler 
    // the registry user won't be able to use the handler:
    B. PacketHandler<? extends Packet>
    // Type mismatch: cannot convert from 
    C. PacketHandler<Packet> 

.. ii) :

class HandlerSwitchExample {
    public static void main() {
        // [...]
        <<OBJECT TYPE>> handler = HandlersRegistry.getHandler(somePacket);
        handler.handle(somePacket);
    }
}

, . , .

+4
2

(Packet PacketHandler), . ( ThatHandler)

  Packet ------------> PacketHandler
    ^                        ^
    |                        |
ThisPacket --------> ThisPacketHandler

. , factory .

(, , Packet:

abstract class Packet<T extends Packet<T>> {
  /**
   *  Factory method.
   *  Override this method in sub-packets to return appropriate handlers
   */
  abstract PacketHandler<T> getHandler();
}

:

class ThisPacket extends Packet<ThisPacket> {
  @Override
  PacketHandler<ThisPacket> getHandler() {
    return new ThisPacketHandlerImpl();
  }
}

class ThatPacket extends Packet<ThatPacket> {
  @Override
  PacketHandler<ThatPacket> getHandler() {
    return new ThatPacketHandlerImpl();
  }
}

PacketHandlers ( ):

interface PacketHandler<P extends Packet<P>> {
  boolean handle(P p);
}

class ThisPacketHandlerImpl implements PacketHandler<ThisPacket> {
  @Override
  public boolean handle(ThisPacket p) {
    return false;
  }

}

class ThatPacketHandlerImpl implements PacketHandler<ThatPacket> {
  @Override
  public boolean handle(ThatPacket p) {
    return false;
  }
}

, :

class HandlersRegistry {
  static <P extends Packet<P>> PacketHandler<P> getHandler(P p) {
    return p.getHandler();
  }
}

:

ThisPacket somePacket = new ThisPacket();
PacketHandler<ThisPacket> handler = HandlersRegistry.getHandler(somePacket);
handler.handle(somePacket);

, , . Packet PacketHandler. getHandler() Packet, . .

+3

Generic :

  • -, , .
  • -, ( HandlerSwitchExample T).

PacketHandler handler = HandlersRegistry.getHandler(somePacket);

static PacketHandler getHandler(Packet p) {
    if (p instanceof ThisPacket) return new ThisPacketHandler();
    if (p instanceof ThatPacket) return new ThatPacketHandler();
    return null;
}

HandlersRegistry .

, , , , . , API, , , .

+1

All Articles