为什么 Java 泛型不支持原始类型?
为什么 Java 中的泛型适用于类,但不适用于原始类型?
例如,这工作正常:
List<Integer> foo = new ArrayList<Integer>();
但这是不允许的:
List<int> bar = new ArrayList<int>();
Why do generics in Java work with classes but not with primitive types?
For example, this works fine:
List<Integer> foo = new ArrayList<Integer>();
but this is not allowed:
List<int> bar = new ArrayList<int>();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Java 中的泛型完全是编译时构造 - 编译器将所有泛型使用转换为正确类型的强制转换。这是为了保持与以前的 JVM 运行时的向后兼容性。
这:(
大致)变成:
因此,任何用作泛型的东西都必须可转换为对象(在此示例中
get(0)
返回一个Object
),而原始类型则不然。因此它们不能用于泛型。Generics in Java are an entirely compile-time construct - the compiler turns all generic uses into casts to the right type. This is to maintain backwards compatibility with previous JVM runtimes.
This:
gets turned into (roughly):
So, anything that is used as generics has to be convertable to Object (in this example
get(0)
returns anObject
), and the primitive types aren't. So they can't be used in generics.在 Java 中,泛型以它们的方式工作......至少部分......因为它们是在语言设计多年后添加到语言中的1。语言设计者在泛型选择上受到限制,因为必须提出与现有语言和 Java 类库向后兼容的设计。
其他编程语言(例如 C++、C#、Ada)确实允许将原始类型用作泛型的参数类型。但这样做的另一面是,此类语言的泛型(或模板类型)实现通常需要为每个类型参数化生成泛型类型的不同副本。
1 - Java 1.0 中未包含泛型的原因是由于时间压力。他们认为必须尽快发布 Java 语言,以填补 Web 浏览器带来的新市场机会。詹姆斯·高斯林表示,如果他们有时间的话,他希望将仿制药纳入其中。如果发生这种情况,Java 语言会是什么样子谁也说不准。
In Java, generics work the way that they do ... at least in part ... because they were added to the language a number of years after the language was designed1. The language designers were constrained in their options for generics by having to come up with a design that was backwards compatible with the existing language and the Java class library.
Other programming languages (e.g. C++, C#, Ada) do allow primitive types to be used as parameter types for generics. But the flip side of doing this is that such languages' implementations of generics (or template types) typically entail generation of a distinct copy of the generic type for each type parameterization.
1 - The reason generics were not included in Java 1.0 was because of time pressure. They felt that they had to get the Java language released quickly to fill the new market opportunity presented by web browsers. James Gosling has stated that he would have liked to include generics if they had had the time. What the Java language would have looked like if this had happened is anyone's guess.
在java中,泛型是通过使用“类型擦除”来实现向后兼容的。
所有泛型类型都会在运行时转换为对象。
例如,
在运行时将被视为
编译器负责提供正确的强制转换以确保类型安全。
将变成
现在的问题是为什么选择“Object”作为运行时的类型?
仅供参考:Project Valhalla 正在尝试解决上述问题。
In java generics are implemented by using "Type erasure" for backward compatibility.
All generic types are converted to Object at runtime.
for example,
will be seen at runtime as,
compiler is responsible to provide proper cast to ensure type safety.
will become
Now the question is why "Object" is chose as type at runtime?
FYI : Project Valhalla is trying to address above issue.
根据 Java 文档,泛型类型变量只能是使用引用类型实例化,而不是原始类型。
这应该出现在 Java 10 的 Project Valhalla 下。
在 Brian Goetz 论文中 专业化状态
有一个 关于原语不支持泛型的原因的精彩解释。并且,如何实施 Java 的未来版本。
。
As per Java Documentation, generic type variables can only be instantiated with reference types, not primitive types.
This is supposed to come in Java 10 under Project Valhalla.
In Brian Goetz paper on State of the Specialization
There is an excellent explanation about the reason for which generic were not supported for primitive. And, how it will be implemented in future releases of Java.
...
这些集合被定义为需要从
java.lang.Object
派生的类型。基本类型根本不这样做。The collections are defined to require a type which derives from
java.lang.Object
. The basetypes simply don't do that.