我有一个类将包含一些针对不同对象的不同解析器实现.虽然我能够在没有任何警告的情况下存储解析器实现,但是从地图获取解析器会警告未经检查的强制转换异常.以下是简化的摘录:
private Map, Parser>> parsers = new HashMap<>();
public void addParser(Class type, Parser parser) {
parsers.put(type, parser);
}
private Parser parserFor(Class type) {
// Compiler complains about unchecked cast below
return (Parser) parsers.get(type);
}
是否有其他方法可以实现类似的逻辑而不会导致未经检查的强制警告?
解决方法:
无法创建Map< Class< ...>,Parser< ...>>其中……-s可以是任何东西,但必须在一个键和它的值之间匹配;所以你无法让编译器为你做检查,在那里检索一个Class< T>保证给你一个Parser< T>.但是,您的代码本身是正确的;你知道你的演员是正确的,即使编译器没有.
所以,当你知道你的演员是正确的,但Java不知道,你能做什么?
最好和最安全的方法是制作一个尽可能小的代码的特定部分,负责处理已检查和未检查逻辑之间的转换,并确保未经检查的逻辑不会导致任何错误.然后,您只需使用相应的@SuppressWarnings注释标记该代码.例如,你可以这样:
public abstract class Parser {
private final Class mType;
protected Parser(final Class type) {
this.mType = type;
}
public final Class getType() {
return mType;
}
@SuppressWarnings("unchecked")
public final Parser castToParserOf(final Class type) {
if (type == mType) {
return (Parser) this;
} else {
throw new ClassCastException("... useful message ...");
}
}
}
在您的示例中,这将允许您安全地编写:
public void addParser(final Parser parser) {
parsers.put(parser.getType(), parser);
}
private Parser parserFor(final Class type) {
return parsers.get(type).castToParserOf(type);
}
标签:java,generics
来源: https://codeday.me/bug/20190623/1275594.html