Java泛型快速介绍 - Prakhar


假设编写了以下类:

public class MessagePublisher extends AMQPublisher{
  public String message;
  public MessageEncoder messageEncoder;
  
  public MessagePublisher(String message) {
    super(); //Assume AMQPublisher has a NoArgs constructor
    
    this.message = message;
    this.messageEncoder = new MessageEncoder();
  }
  
  public void publishMessage() throws MessageEncodingException {
    final EncodedMessage encodedMessage = messageEncoder.encode(message);
    sendMessage(encodedMessage);
  }
}

现在,假设我们要为另一条消息做同样的事情,只是这次消息不是字符串类型,而是是整数、双数或枚数?
我们是否需要再写3到4个类,其中95%的代码都是一样的?
不,只要你知道泛型。

以上述例子为例,我们将需要做一些修改:

public class MessagePublisher<T> extends AMQPublisher{
  public T message;
  public MessageEncoder messageEncoder;
  
  public MessagePublisher(T message) {
    super(); //Assume AMQPublisher has a NoArgs constructor
    
    this.message = message;
    this.messageEncoder = new MessageEncoder();
  }
  
  public void publishMessage() throws MessageEncodingException {
    final EncodedMessage encodedMessage = messageEncoder.encode(message);
    sendMessage(encodedMessage);
  }
}

你会注意到,我们已经把所有出现的String message替换成了T message,其中T是一个参数化的类型引用,与类名一起声明。
注意:虽然我们把它看作是T,但你可以给它起任何名字 尽管社区中大多数人都使用T,所以保持这种方式是很好的,这样如果有新的人进来查看代码,他们就不会为一个不寻常的参数化类型符号而苦恼。

让我们访问同一个例子,看看如何使其发挥作用。

public class Main {
  
  static {
    final String stringMessage = "Message";
    final Integer intMessage = 5;
    final Float floatMessage = 5.0;
    
    MessagePublisher<String> stringMessagePublisher = new MessagePublisher<>(stringMessage);
    MessagePublisher<Integer> intMessagePublisher = new MessagePublisher<>(intMessage);
    MessagePublisher<Float> floatMessagePublisher = new MessagePublisher<>(floatMessage);
    
    List<MessagePublisher> messagePublisherList = new ArrayList<>();
    messagePublisherList.append(stringMessagePublisher);
    messagePublisherList.append(intMessagePublisher);
    messagePublisherList.append(floatMessagePublisher);
  }
  
  public static void main(String[] args) {
   
// Publish all messages.
    messagePublisherList.stream().forEach(this::publishMessage);
  }
}