有 Java 编程相关的问题?

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

Java泛型从映射中放置和检索泛型接口的实现

我有一个关于java泛型的问题。假设我创建了这个简单的界面:

public interface ToString {

    String toString(Message message);
}

以及实现此功能的类:

public class GoldMessageToStringer implements ToString  {

    @Override
    public String toString(Message message) {
        GoldMessage myMessage = (GoldMessage) message;
    }
}  

我正在实例化地图来保存我的ToString实现,这样我就可以快速、安全地获取它们:

private static final Map<Message.Type, ToString> toStringer = initializeToStringers();

private static Map<Message.Type, ToString> initializeToStringers() {
   Map<Message.Type, ToString> map = new HashMap<>();
   map.put(Message.Type.A, new GoldMessageToStringer();
   return map;
}

String toStringMessage(Message message) {
   toStringer.get(message.getType()).toString(message);
}  

对我来说最难看的是GoldMessageToStringer中的强制转换,所以我决定参数化ToString接口,以便在实现中使用类型:

public interface ToString<T extends Message> {

    String toString(T message);
}

public class GoldMessageToStringer implements ToString<GoldMessage>  {

    @Override
    public String toString(GoldMessage message) {
        GoldMessage myMessage = message;
    }
}    

但现在,由于类型不兼容,我无法提供、获取或将ToString实现放入map(第三个代码段),或者至少在最好的情况下以unchecked cast结尾。我可能把泛型和继承混为一谈了什么是Java不允许的,对吧?如何根据最佳/常见做法进行

第一次尝试-未指定泛型类型:

private static final Map<Message.Type, ToString> toStringer = initializeToStringers();

private static Map<Message.Type, ToString> initializeToStringers() {
   Map<Message.Type, ToString> map = new HashMap<>();
   map.put(Message.Type.A, new GoldMessageToStringer();
   return map;
}

String toStringMessage(Message message) {
   toStringer.get(message.getType()).toString(message); // unchecked cast
}  

第二次尝试-指定的泛型类型:

private static final Map<Message.Type, ToString<Message>> toStringer = initializeToStringers();

private static Map<Message.Type, ToString<Message>> initializeToStringers() {
   Map<Message.Type, ToString<Message>> map = new HashMap<>();
   map.put(Message.Type.A, new GoldMessageToStringer(); // not compiles, requring ToString<Message>, got GoldMessageToStringer
   return map;
}

String toStringMessage(Message message) {
   toStringer.get(message.getType()).toString(message); 
}   

第三次尝试-指定类型边界:

 private static final Map<Message.Type, ToString<? extends Message>> toStringer = initializeToStringers();

    private static Map<Message.Type, ToString<? extends Message>> initializeToStringers() {
       Map<Message.Type, ToString<? extends Message>> map = new HashMap<>();
       map.put(Message.Type.A, new GoldMessageToStringer(); 
       return map;
    }

    String toStringMessage(Message message) {
       toStringer.get(message.getType()).toString(message);  // not compiles, Message cannot be applied to ? extends Message
    }   

第四次尝试-未经检查的演员阵容,最干净的imho:

private static final Map<Message.Type, ToString<Message>> encoders = initializeToStringers();

String toStringMessage(Message message) {
    toStringer.get(message.getType()).toString(message);
}

private static Map<Message.Type, ToString<Message>> initializeToStringers() {
    Map<Message.Type, ToString<Message>> toStringers = new HashMap<>();
    put(toStringers, Message.Type.A, new GoldMessageToStringer());
    return encoders;
}

@SuppressWarnings("unchecked")
private static <T extends Message> void put(Map<Message.Type, ToString<T>> map, MessageType type, ToString toStringer) {
    map.put(type, toStringer);
}

共 (0) 个答案