繁体   English   中英

Java泛型 - <int> 至 <Integer>

[英]Java Generics - <int> to <Integer>

在学习Java Generics的过程中,我陷入了困境。
它写成“ Java Generics仅适用于Objects而不适用于原始类型 ”。

例如

 Gen<Integer> gen=new Gen<Integer>(88);     // Works Fine ..  

但是,使用int,char等原始类型...

 Gen<int> gen=new Gen<int>(88) ;    // Why this results in compile time error 

我的意思是说,因为java泛型确实具有自动装箱和拆箱功能,那么当我们为我们的类声明特定类型时,为什么不能应用此功能呢?

我的意思是,为什么Gen<int>不会自动转换为Gen<Integer>

请帮我清除这个疑问。
谢谢。

Autoboxing并没有说你可以使用int而不是Integer。 自动装箱自动化装箱和拆箱过程。 例如,如果我需要将一些原始int存储到集合中,我不需要手动创建wrpper对象。 Java编译器一直在关注它。 在上面的示例中,您将实例化一个Integer类型的泛型对象。 这个泛型对象仍然可以正常使用int,但将int声明为泛型类型是错误的。 泛型只允许对象引用而不是基元。

正如您所发现的,您不能在Java泛型中将原始类型作为类型参数提及。 为什么会这样? 它在很多地方都有详细讨论,包括Java bug 4487555

简单的解释:泛型是这样定义的。

从Java的角度来看,这是一个很好的理由:它简化了类型擦除和转换为编译器的字节代码。 所有编译器需要做的是一些转换。

随着非原语编译器将不得不决定是否投或收件箱/发件箱,那就需要有额外的验证规则( extends&将没有任何意义与原语,应在?包括原语,是或否?等等)并且必须处理类型转换(假设您使用long参数化一个集合并添加一个int ...?)

从程序员的角度来看,这是一个很好的理由:性能不佳的操作是可见的! 允许原始作为类型参数将需要隐藏的自动装箱(用于存储的收件箱,用于读取操作的发件箱。收件箱可能会创建昂贵的新对象。如果他们使用基元对泛型类进行参数化,人们会期望快速操作,但情况恰恰相反。

这是一个非常好的问题。

正如您所怀疑的那样,抽象肯定可以扩展到类型参数,并使它们对程序员来说是透明的。 实际上,这就是大多数现代JVM语言所做的事情(当然是静态类型的)。 例子包括Scala,Ceylon,Kotlin等。

这就是您的示例在Scala中的样子:

val gen: Gen[Int] = new Gen[Int](80)

Int只是一个普通的类,就像其他类一样。 没有任何原始对象的区别。

至于为什么Java人没有这样做......我实际上并不知道原因,但我认为这样的抽象不适合现有的Java规范而不会过度复杂语义(或者不会牺牲向后兼容性,这当然是肯定的不是一个可行的选择)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM