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) 个答案