Java与泛型一起使用接口

示例

假设您要定义一个接口,以允许在不同类型的通道(例如AMQP,JMS等)之间发布数据或从中使用数据,但是您希望能够切换出实现细节...

让我们定义一个可以在多个实现中重复使用的基本IO接口:

public interface IO<IncomingType, OutgoingType> {

    void publish(OutgoingType data);
    IncomingType consume();
    IncomingType RPCSubmit(OutgoingType data);

}

现在我可以实例化该接口,但是由于我们没有这些方法的默认实现,因此在实例化该接口时需要一个实现:

    IO<String, String> mockIO = new IO<String, String>() {

        private String channel = "somechannel";

        @Override
        public void publish(String data) {
            System.out.println("Publishing " + data + " to " + channel);
        }

        @Override
        public String consume() {
            System.out.println("从消费 " + channel);
            return "some useful data";
        }

        @Override
        public String RPCSubmit(String data) {
            return "received " + data + " just now ";
        }

    };

    mockIO.consume(); // prints: 从消费 somechannel
    mockIO.publish("TestData"); // 将TestData发布到某个频道
    System.out.println(mockIO.RPCSubmit("TestData")); // 刚收到TestData

我们还可以对该接口做一些更有用的事情,假设我们想用它包装一些基本的RabbitMQ函数:

public class RabbitMQ implements IO<String, String> {

    private String exchange;
    private String queue;

    public RabbitMQ(String exchange, String queue){
       this.exchange= exchange;
       this.queue= queue;
    }

    @Override
    public void publish(String data) {
        rabbit.basicPublish(exchange, queue, data.getBytes());
    }

    @Override
    public String consume() {
        return rabbit.basicConsume(exchange, queue);
    }

    @Override
    public String RPCSubmit(String data) {
        return rabbit.rpcPublish(exchange, queue, data);
    }

}

假设我现在想使用此IO接口作为自上次系统重启以来计算对我的网站的访问的一种方式,然后能够显示访问的总数-您可以执行以下操作:

import java.util.concurrent.atomic.AtomicLong;

public class VisitCounter implements IO<Long, Integer> {

    private static AtomicLong websiteCounter = new AtomicLong(0);
    
    @Override
    public void publish(Integer count) {
        websiteCounter.addAndGet(count);
    }

    @Override
    public Long consume() {
        return websiteCounter.get();
    }

    @Override
    public Long RPCSubmit(Integer count) {
        return websiteCounter.addAndGet(count);
    }
    
}

现在,我们使用VisitCounter:

    VisitCounter counter = new VisitCounter();

    // 刚来过4次
    counter.publish(4);
    // 刚再来一次,是的
    counter.publish(1);

    // 获取统计计数器的数据
    System.out.println(counter.consume()); // 版画5

    // 显示统计信息计数器页面的数据,但将其作为页面视图包含在内
    System.out.println(counter.RPCSubmit(1)); // 版画6


实现多个接口时,不能两次实现相同的接口。这也适用于通用接口。因此,以下代码无效,并会导致编译错误:

interface Printer<T> {
    void print(T value);
}

// 无效!
class SystemPrinter implements Printer<Double>, Printer<Integer> {
    @Override public void print(Double d){ System.out.println("Decimal: " + d); }
    @Override public void print(Integer i){ System.out.println("Discrete: " + i); }
}