为什么Java中的数据类型不是对象?

4

我很早就学过Java数据类型,发现它们是原始类型。尽管Java是面向对象的语言,但其数据类型并不是对象。这是为什么呢?


1
为什么它没有被定义为对象,或者为什么Java的设计者选择将原始类型定义为非对象? - amit
@amit 可能是因为 Java 之前的编程语言,例如 C++,对 Java 的设计产生了影响,所以 Java 也采用了相同的方式。完全可以编写一个编译器,假装 ints 等是对象,并在背后使用基础平台的原始类型,这样就像高级语言将原始类型暴露在语言中一样高效。 - Jesper
@Jesper:我正在尝试理解OP在“为什么Java中的数据类型不是对象?”中的意思。它可以被解释为两个问题 - 定义(是什么使它们与对象不同?)和设计(为什么设计者选择这样做?)。 - amit
你的术语非常混淆。在Java中,原始类型不是对象,但“数据类型”一词并不限于原始类型。 - user207421
5个回答

4
据说Java中的所有内容都是对象,同时Java编程语言旨在简单易懂。因为原始数据类型占用内存小且访问速度快,所以它们不是对象。Java中也有等效的包装类,例如"Integer"、"Short"等,如果需要可以将它们用作对象。但是,包装类将存储在堆中,速度比较慢。

3
这是两件事的组合。
1. 这是一种语言设计偏好/选择。Java语言设计者明显认为基本类型与对象不同...数组类型与类也不同。这种观点并非独此一家,许多其他面向对象的语言设计也有这种区分。
2. 将诸如数字类型等基本类型变成完整的对象类型确实会有代价。
Jesper指出(在另一个答案的评论中)一些语言将OO数值类型映射到硬件支持的类型下。然而,他没有提到只有在对它们进行限制时才能使其正常工作。您只能对编译器已知的数字类型以及叶子类型(即没有自定义子类型的类型)执行此操作。
如果数值类型不是叶子类型,则无法表示为本地类型,因为没有办法实现这一点:
  class MyInteger extends Integer /* a builtin numeric type */ {
      public ... add(...) { /* a different way of doing addition */ }
  }

为什么?因为内置类型表示为本地硬件整数类型,无法在这种表示上进行派发。
简而言之,要么对象数字(等等)类型速度慢且使用比等价的Java原始类型更多的内存,要么这些类型被限制使你难以利用其面向对象的特性。

Scala是一种语言,它具有像类一样行为的类型IntLong等,但映射到JVM的intlong等原语。有一个提案添加值类到Scala;您可以创建自己的类,将其映射到JVM原始类型。对于值类将有限制,您不能像“普通”类那样做所有事情。 - Jesper

3

更加高效的处理方式是使用基本类型,而不是将每个变量作为完整的对象。最常见的类型(例如int、char、float等)是简单的基本类型,其余则是对象。


@kundanbora - 是的,但你真的认为如果原始类型的操作很慢,Java会成为主流语言吗?仅仅为了满足一些人对OO纯洁性的愿望? - Stephen C
@StephenC,我认为Java已经是一种很好的语言了。但我的问题是,将数据设置为基元类型比对象更有效率,那么为什么我们将所有其他内容都存储在对象中。Java也提供了基元数据类型的包装类。 - kundan bora
还有其他语言,它们假装整数等是对象。在幕后,编译器生成处理它们作为底层平台的原始类型的代码。高级语言不需要直接公开底层平台的原始类型,这只是Java语言设计者所做的选择。 - Jesper
@ Jesper - 请看我的答案,我已经回应了您的评论。 - Stephen C

2
在Java中,所有的对象类型都可以用基本类型和对象引用来定义。
基本类型和引用是无法用其他类型来定义的类型。
一些语言会隐藏这种区别,这实际上使得基本类型更高级,如果开发者不关心差异,则可以使其生活更轻松,但如果他们关心,则会变得更加困难。
很少有真正的语言是纯面向对象、纯函数式或纯逻辑语言,你必须做出一些实用性的选择才能使语言可用。

0

性能和内存占用是使用基本数据类型而不是完整对象的良好理由。


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