有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java有没有办法通过使用泛型来避免instanceof?

我有一个流程,其中多个位置可以生成错误消息和成功消息,因此我希望使用一个类来跟踪它们,然后在流程结束时,按不同的“类型”对消息进行分组。 大致如下:

public class Message {
  String message;
  public Message(String message) {
      this.message = message;
  }
}

public class ErrorMessage extends Message {};
public class FileErrorMessage extends ErrorMessage {};
public class OkMessage extends Message {};

等等。(为了清楚起见,我跳过了派生类中的构造函数)。我可以通过使用instanceof操作符来区分列表,但是我认为泛型会更优雅,但是我如何在列表中区分它们呢

Message<ErrorMessage> eMsg = new Message<ErrorMessage>("invalid user");
Message<FileErrorMessage> feMsg = new Message<FileErrorMessage>("file not found");

我想过使用枚举

enum MessagType { ERROR, FILE_ERROR, OK }

对于不同的类,但我无法想出一个解决方案。谢谢


共 (2) 个答案

  1. # 1 楼答案

    在这种情况下,您通常可以做的是使Message具有一个可以被子类重写的函数。然后,调用该函数时,每个子类都可以有自己的行为,也可以保留消息的默认行为。如果默认值没有意义,那么可以将消息设置为抽象类

    然后,您可以循环浏览列表并执行以下操作:

    for (Message m : messages) {
        m.function();
    }
    

    希望这就是你想要的

    编辑:为了回应你下面的评论,你可以这样做(用番石榴):

    SetMultimap<Class, Message> messagesByType = HashMultimap.create();
    for (Message m : messages) {
        messagesByType.add(m.getClass(), m);
    }
    

    然后可以通过messagesByType进行嵌套循环,一次处理一种不同的类型。尽管如此,考虑到我最初的回答,我并不认为有必要这样做,但这是为了回答你的问题

  2. # 2 楼答案

    在这种情况下使用泛型对我来说毫无意义。如果不同类型的消息具有不同的行为,那么使用继承来区分消息的类型是有意义的,但事实似乎并非如此

    因此,我将消息的类型作为Message类的属性:

    enum MessageType { ERROR, FILE_ERROR, OK }
    
    public class Message {
    
        private final String message;
    
        private final MessageType type;
    
        public Message(String message, MessageType type) {
            this.message = message;
            this.type = type;
        }
    
        public MessageType getType() {
            return this.type;
        }
    
        // getter for message
    }
    

    一般来说,应该保持简单,参见KISS principle

    编辑:

    如果要按类型对邮件进行分组,可以按如下操作:

    Map<MessageType, Message> messagesByType = messages.stream()
        .collect(Collectors.groupingBy(Message::getType));
    

    messages是包含所有消息的List