为什么Java中会有原始数据类型?

15

为什么Java不是纯面向对象的语言? - PermGenError
@GanGnaMStYleOverFlowErroR:它没有解释为什么会有原始类型。 - Felix Kling
2
有传言称原始类型将在Java 10中消失。 - assylias
@user2003432 请查看此链接 http://stackoverflow.com/questions/12670817/java-is-not-purely-object-oriented-what-does-this-mean-w-r-t-primitve-types - SANN3
@GanGnaMStYleOverFlowErroR 不,包装类(如Integer等)自Java 1.0以来就存在了;它们在Java 1.4中并不是新的。 - Jesper
显示剩余5条评论
3个回答

34
为了提高效率,原始类型的变量直接包含值;非原始类型的变量是引用,指向存储在内存中其他地方的对象。
每次需要使用包装器类型的值时,JVM 都需要查找内存中的对象以获取值。这对于原始类型不需要,因为变量本身就包含值,而不是指向包含值的对象的引用。
然而,这并不能解释为什么原始类型需要在 Java 编程语言中显式可见。Java 语言和 JVM 的设计者本可以选择隐藏原始类型,使您可以将所有东西都视为对象;编译器可以将其在底层转换为更有效的原始类型。
一些在 JVM 上运行的较新的编程语言(Groovy、Scala 等)正是这样做的:在语言本身中,一切看起来都像一个对象,您可以在上面调用方法,但在底层,编译器将它们转换为原始类型。
我想,在 Java 语言开发的时候(20 世纪 90 年代上半期),人们没有考虑到这一点,现在已经太晚了,无法进行根本性的语言修改以允许这一点。

7

原始数据类型存在的主要原因是创建对象、分配堆栈太昂贵,而且会带来性能损失。正如你所知,像int、float 等基本数据类型最常用,所以将它们作为对象化将会产生巨大的性能损失。因此,Java 的设计者认为将其作为非对象更好。 当然,如果你准备在性能上做出一点牺牲,但需要更多的面向对象编程功能,那么就可以使用包装器。在这种情况下,你可以使用包装器。希望这些信息对你有所帮助。


创建对象,分配堆内存成本太高,而且会有性能损失。 => 你有参考资料吗?虽然会有一些性能损失,但并不是那么高。 - assylias
例如,Goetz指出:“在HotSpot 1.4.2及更高版本中,创建新对象的常见代码路径大约包含10条机器指令。” - assylias
原始类型表示单个值,而不是复杂对象。尽管Java在其他方面完全面向对象,但原始类型并非如此。它们类似于大多数其他非面向对象语言中的简单类型。这样做的原因是效率。将原始类型转换为对象会严重降低性能。 - Pradeep Simha
@assylias,是的,这个惩罚可能较小,但在创建更多的int、float包装器的情况下,你可以观察到这种惩罚。 - Pradeep Simha

2

出于性能考虑,在其他一些语言中,如SmallTalk,像int或char这样的类型也是对象,并且可以在它们上面调用方法。这更符合理论,但当前的实现速度较慢。原始类型是纯度和性能之间的折衷。

在必要时(可能存在null值或与集合框架一起使用),Java提供了包装类,例如java.lang.Integer等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接