编译器能合理地推断类型参数吗? 是的,在示例情况下-static HashMap<K,V>newInstance(){return new HashMap<>();}显然是static < K extends Object , V extends Object > HashMap<K,V>newInstance()return new HashMap<K,V>();}的缩写。 但是如果你的编译器推断出了类型参数,那么即使你输入了错误的类名,你的代码仍然可以编译。static void setName ( Sting name )可能是错误的,但是你的编译器会认为你的意思是<Sting extends Object> static void setName ( Sting name );通过运行时擦除的魔力,它等价于static void setName ( Object name ) ;。 如果方法不是静态的,那么推断就有问题。class X { HashMap<K,V>newInstance(){return new HashMap<>();}}可以被类型推断为以下之一:
class X <K extends Object , V extends Object> { HashMap<K,V>newInstance(){return new HashMap<>();}}
class X <K extends Object > { < V extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
class X <V extends Object> { < K extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
class X { <K extends Object , V extends Object> HashMap<K,V>newInstance(){return new HashMap<>();}} 另外,如果类型参数被推断,那么顺序是什么。当它们被显式声明时,顺序很明显唯一的(对我来说很明显)解决推断类型参数的顺序问题的方法是它们在代码中声明的顺序。(这应该是无关紧要的)你可能会改变公共接口,破坏构建。太脆弱了!
4条答案
按热度按时间mftmpeh81#
使用/返回泛型类型来指示该方法是泛型方法。如果它们不存在,编译器将查找名为K的“真实的类型”(即类或接口)和名为V的另一个实类型。
vq8itlhq2#
因为函数
newInstance
也是泛型的,泛型类型 K 和 V 被转发到HashMap
。它的用法是这样的:9avjhtql3#
除此之外,擦除在编译时会丢失所有的类型。然而,编译器会首先检查验证,这就是为什么需要这些类型。
以下是从另一个SO answer擦除后发生的情况的示例:
但是当使用泛型时,它们被转换为编译时检查和执行时强制转换。
列表list = new数组列表();list.add();String x = list.get(0);
被编译成
列表list = new数组列表();list.add();String x =(String)list.get();
13z8s7eq4#
编译器能合理地推断类型参数吗?
是的,在示例情况下-
static HashMap<K,V>newInstance(){return new HashMap<>();}
显然是static < K extends Object , V extends Object > HashMap<K,V>newInstance()return new HashMap<K,V>();}
的缩写。但是如果你的编译器推断出了类型参数,那么即使你输入了错误的类名,你的代码仍然可以编译。
static void setName ( Sting name )
可能是错误的,但是你的编译器会认为你的意思是<Sting extends Object> static void setName ( Sting name );
通过运行时擦除的魔力,它等价于static void setName ( Object name ) ;
。如果方法不是静态的,那么推断就有问题。
class X { HashMap<K,V>newInstance(){return new HashMap<>();}}
可以被类型推断为以下之一:class X <K extends Object , V extends Object> { HashMap<K,V>newInstance(){return new HashMap<>();}}
class X <K extends Object > { < V extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
class X <V extends Object> { < K extends Object > HashMap<K,V>newInstance(){return new HashMap<>();}}
class X { <K extends Object , V extends Object> HashMap<K,V>newInstance(){return new HashMap<>();}}
另外,如果类型参数被推断,那么顺序是什么。当它们被显式声明时,顺序很明显唯一的(对我来说很明显)解决推断类型参数的顺序问题的方法是它们在代码中声明的顺序。(这应该是无关紧要的)你可能会改变公共接口,破坏构建。太脆弱了!