Check class type

How i can check if a class is of a determinated type for example:

// PacketHandler.java

public interface PacketHandler<T> {
    public void handlePacket(T packet);
}


// PacketReader.java

public void read() {
    Packet packet = // Read some input
    for(PacketHandler packetHandler : packetHandlers) {
        if  (packetHandler is the type of packet) { // here is the problem
            packetHandler.handlePacket(packet);
        }
    }
}

public void registerHandler(PacketHandler<?> packetHandler) {
    packetHandlers.add(packetHandler);
}

// Main

packetReader.registerHandler(new PacketHandler<RandomPacket>() {
    public void handlePacket(RandomPacket packet) {
        // I handle the packet
    }
});

I know that this question maybe seems stupid; but how to solve this problem?

**Edit*****

Jon Skeet, so the class should be:

public class RandomClass implements PacketHandler {
    public boolean handlePacket(Packet packet) {
       if (packet instanceof PacketThatThisClassHandle) {
          //handle with casting
          return true;
       } else {
          return false;
       }
    }
}
Jon Skeet
people
quotationmark

Unfortunately Java generics use type erasure, meaning that at execution time, any particular PacketHandler<T> is just PacketHandler as far as the VM is concerned.

You may want to change your code to:

public interface PacketHandler {
    // The parameter type can  be Object if you really want
    boolean tryHandlePacket(Packet packet);
}

... and make a PacketHandler just return false if it doesn't know how to handle a particular packet type.

Then you can just use:

for (PacketHandler handler : handlers) {
    if (handler.tryHandlePacket(packet)) {
        break;
    }
}

(That's assuming you only want a single handler to actually handle any packet type.)

If you still want a generic interface, you'd either need a boolean handlesPacket(Packet) method, or possibly a Class<T> getPacketType() method. Either way it's still going to be a pain in terms of casting the packet to the right type...

If you have lots of packet handlers, you could potentially create an abstract base class:

public abstract class AbstractPacketHandler<T extends Packet>
    implements PacketHandler {

    private final Class<T> packetType;

    protected AbstractPacketHandler(Class<T> packetType) {
        this.packetType = packetType;
    }

    protected abstract void handlePacket(T packet);

    public boolean tryHandlePacket(Packet packet) {
        if (!packetType.isInstance(packet)) {
            return false;
        }
        handlePacket(packetType.cast(packet));
        return true;
    }
}

Then you can write:

public class FooPacketHandler extends PacketHandler<Foo> {
    public FooPacketHandler() {
        super(Foo.class);
    }

    protected void handlePacket(Foo packet) {
        ...
    }
}

people

See more on this question at Stackoverflow