为了账号安全,请及时绑定邮箱和手机立即绑定

请问为什么这个通用java代码不会编译?

请问为什么这个通用java代码不会编译?

慕虎7371278 2019-09-05 10:05:10
为什么这个通用java代码不会编译?在这个简化的例子中,我有一个泛型类,以及一个返回Map而不管类型参数的方法。当我没有在包含类上指定类型时,为什么编译器会清除地图上的类型?import java.util.Map;public class MyClass<T>{     public Map<String, String> getMap()     {            return null;     }     public void test()     {            MyClass<Object> success = new MyClass<Object>();         String s = success.getMap().get("");         MyClass unchecked = new MyClass();         Map<String, String> map = unchecked.getMap();  // Unchecked warning, why?         String s2 = map.get("");         MyClass fail = new MyClass();         String s3 = fail.getMap().get("");  // Compiler error, why?     }}我得到这个编译错误。MyClass.java:20: incompatible types found   : java.lang.Objectrequired: java.lang.String                 String s3 = fail.getMap().get("");  // Compiler error
查看完整描述

3 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞


得到它了。这实际上不是一个错误,看起来很奇怪。


从JLS的4.8节(原始类型):


未从其超类或超接口继承的原始类型C的构造函数(第8.8节),实例方法(第8.8节,第9.4节)或非静态字段(第8.3节)M的类型是其类型的擦除在对应于C的泛型声明中。原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同。


因此,即使方法的类型签名不使用类本身的任何类型参数,类型擦除也会启动并且签名变得有效


public Map getMap()

换句话说,我想你能想象一个原始类型为相同的API泛型类型,但所有<X>的移除位随处可见(在API中,未实现)。


编辑:此代码:


MyClass unchecked = new MyClass();

Map<String, String> map = unchecked.getMap();  // Unchecked warning, why?

String s2 = map.get("");

编译,因为从原始Map类型到隐式但未经检查的转换Map<String, String>。通过在最后一种情况下进行显式转换(在执行时无效),您可以获得相同的效果:


// Compiles, but with an unchecked warning

String x = ((Map<String, String>)fail.getMap()).get("");



查看完整回答
反对 回复 2019-09-07
?
达令说

TA贡献1821条经验 获得超6个赞

嗯...不幸的是我无法告诉你它失败的原因。但我可以给你一个简单的解决方法:

改变的类型failMyClass<?>,那么它将编译就好了。


查看完整回答
反对 回复 2019-09-07
  • 3 回答
  • 0 关注
  • 414 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信