我使用Spring Boot .yaml进行配置,并使配置类成为层次结构,以便其他应用程序可以定义其他属性。配置本身具有层次结构。
为了保持扩展性,我使用了<? extends Type>
通用声明。
当我尝试将<? extends Type>
减小为Type
时,这会导致问题。
以下完全正常工作的最小示例演示问题(在getSubConfs
方法中):
public static class Conf<S> {
public String name;
public Map<String, S> subConfs;
}
public static class SubConf {
public String name;
public Conf<? extends SubConf> conf;
}
public static Map<String, SubConf> getSubConfs(SubConf subconf) {
// incompatible types: java.util.Map<java.lang.String,capture#1 of ? extends App.SubConf>
// cannot be converted to java.util.Map<java.lang.String,App.SubConf>
return subconf.conf.subConfs;
}
public static void main(String[] args) {
Conf<SubConf> cfg = new Conf<>();
cfg.name = "cfg";
SubConf subcfg = new SubConf();
subcfg.name = "subcfg";
subcfg.conf = cfg;
cfg.subConfs = new HashMap<>();
cfg.subConfs.put(subcfg.name, subcfg);
Map<String, SubConf> subConfs = getSubConfs(subcfg);
System.out.println(subConfs.get("subcfg").name);
}
我希望在
getSubConfs(subcfg)
调用时获得Map<String, SubConf>
,因为我不在乎subcfg
的进一步特殊化,我只需要访问公共属性。有效代码为:
public static Map<String, ? extends SubConf> getSubConfs2(SubConf subconf) {
Conf<? extends SubConf> cfg = subconf.conf;
return cfg.subConfs;
}
但是我看不到为什么在运行时没有类型问题的情况下我应该在API中使用
? extends SubConf
的原因。更新功能:
public static Map<String, SubConf> getSubConfs(SubConf subconf) {
Conf<? extends SubConf> cfg = subconf.conf;
return (Map<String, SubConf>) cfg.subConfs;
}
表明即使使用
-XLint:unchecked
,代码也没有任何运行时问题:warning: [unchecked] unchecked cast
return (Map<String, SubConf>) cfg.subConfs;
required: Map<String,SubConf>
found: Map<String,CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends SubConf from capture of ? extends SubConf
当然,我可以用
@SuppressWarnings("unchecked")
装饰函数。 最佳答案
您的方法getSubConfs()
的问题是SubConf.conf
的类型为Conf<? extends SubConf>
。那么Conf.subConfs
的类型为Map<String, ? extends SubConf>
,但是此Map
与您要获取的Map<String, SubConf>
不兼容。
不兼容的原因是,没有办法说明Map<String, ? extends SubConf>
中的SubConf实现。您可以从中读取SubConf值,但不能在其中添加任何内容(最终可能会混合使用不同的实现)。 Map<String, SubConf>
清楚其类型,您可以安全地阅读和添加项目:
// Assuming SubConf2 and SubConf3 both extend SubConf ...
HashMap<String, SubConf2> map = new HashMap<>();
Map<String, ? extends SubConf> subconfMap = map;
// This doesn't work, because then you could call map.get("key")
// and get SubConf3 which is not compatible with the declared SubConf2
subconfMap.put("key", new SubConf3());
// The problem cannot happen with with Map<String, SubConf>, because
// the following statement causes compile time error:
Map<String, SubConf> subconfMap = new HashMap<String, SubConf2>();
关于java - 如何减少泛型<?将Type>扩展为Java中的Type。代码在运行时有效,但无法编译,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43627743/