Java 为什么原始数据类型的内存是固定的?

Java 为什么原始数据类型的内存是固定的?,java,Java,我的问题: 为什么原始数据类型的大小是固定的 集合的大小如何动态增长 假设,基本数据类型还包含动态增大其大小的功能或能力。然后,我们可以将数据类型从8种减少到大约4种,如所有整数组的“Integer”,浮点、短、长和Float,浮点组的数据类型为Double。为什么他们的结构不是这样 任何答案都会有帮助。提前感谢。硬件原语总是有一个定义的大小,否则您将在内存布局、将字节转换为原语以及将字节转换为原语等方面遇到困难。软件原语(由语言提供的内置数据类型)可能不需要固定大小,但这会使内存操作和数据

我的问题:

  • 为什么原始数据类型的大小是固定的

  • 集合的大小如何动态增长

假设,基本数据类型还包含动态增大其大小的功能或能力。然后,我们可以将数据类型从8种减少到大约4种,如所有整数组的“Integer”,浮点、短、长和Float,浮点组的数据类型为Double。为什么他们的结构不是这样


任何答案都会有帮助。提前感谢。

硬件原语总是有一个定义的大小,否则您将在内存布局、将字节转换为原语以及将字节转换为原语等方面遇到困难。软件原语(由语言提供的内置数据类型)可能不需要固定大小,但这会使内存操作和数据传输操作更加复杂

例如,如果要从文件中读取整数,您将读取多少字节?1,2,4,8

在内存中,您也会遇到类似的问题:如果一个对象由两个短整数组成,即2x2字节,那么如果第一个整数需要增长,甚至需要移动整个对象,则需要移动第二个整数。这将是一个性能损失,而不仅仅是因为只有一个整数类型的舒适性而得到补偿


另一方面,集合可以增长,因为它们要么引用堆的不同部分,要么在需要更多空间时将其内容复制到堆的更大部分

ArrayList
为例。在内部,它使用一个位于连续内存块中的数组(否则,通过使用数组地址和元素索引调整来访问内存将不起作用),如果该数组需要增长,则创建一个更大的数组,并将原始数组复制到新数组

另一方面,
LinkedList
分布在堆上,因为每个条目只包含对上一个和下一个条目以及元素的引用。这使得增加列表更容易,但是访问某个元素需要搜索所有元素,直到找到感兴趣的元素为止

另一个例子:

int
值的数组:1,2,3,4,5,6

数组列表(注意JDK不提供基元列表,但还有其他库提供)可以按如下方式存储它们(十六进制值,字节顺序与本例无关):

现在,如果您想访问元素4(索引3),您只需要知道第一个元素的内存地址,并添加
索引*4
字节以获得第四个元素的位置。然后读取接下来的4个字节,就得到了元素值。(4个字节,因为
int
定义为32位,即4个字节)

如果没有这些信息,你将不得不采取更多的行动来获取第四个元素

现在考虑一个链表

Element 0 <-> Element 1 <-> Element 2 <-> Element 3 <-> Element 4 <-> Element 5
  |             |             |             |             |             |
  v             v             v             v             v             v              
Value 1       Value 2       Value 3       Value 4       Value 5       Value 6

如您所见,元素可以位于内存中的任何位置,因此您不能仅通过使用内存地址、索引和元素大小来访问第四个元素。相反,您必须从元素0开始查找元素1,然后查找元素2等,直到找到您要查找的元素。

硬件原语总是有一个定义的大小,否则您在内存布局、将字节转换为原语以及将字节转换为原语等方面会遇到困难。软件原语(由语言提供的内置数据类型)可能不需要固定大小,但这会使内存操作和数据传输操作更加复杂

例如,如果要从文件中读取整数,您将读取多少字节?1,2,4,8

在内存中,您也会遇到类似的问题:如果一个对象由两个短整数组成,即2x2字节,那么如果第一个整数需要增长,甚至需要移动整个对象,则需要移动第二个整数。这将是一个性能损失,而不仅仅是因为只有一个整数类型的舒适性而得到补偿


另一方面,集合可以增长,因为它们要么引用堆的不同部分,要么在需要更多空间时将其内容复制到堆的更大部分

ArrayList
为例。在内部,它使用一个位于连续内存块中的数组(否则,通过使用数组地址和元素索引调整来访问内存将不起作用),如果该数组需要增长,则创建一个更大的数组,并将原始数组复制到新数组

另一方面,
LinkedList
分布在堆上,因为每个条目只包含对上一个和下一个条目以及元素的引用。这使得增加列表更容易,但是访问某个元素需要搜索所有元素,直到找到感兴趣的元素为止

另一个例子:

int
值的数组:1,2,3,4,5,6

数组列表(注意JDK不提供基元列表,但还有其他库提供)可以按如下方式存储它们(十六进制值,字节顺序与本例无关):

现在,如果您想访问元素4(索引3),您只需要知道第一个元素的内存地址,并添加
索引*4
字节以获得第四个元素的位置。然后读取接下来的4个字节,就得到了元素值。(4个字节,因为
int
定义为32位,即4个字节)

如果没有这些信息,你将不得不采取更多的行动来获取第四个元素

现在考虑一个链表

Element 0 <-> Element 1 <-> Element 2 <-> Element 3 <-> Element 4 <-> Element 5
  |             |             |             |             |             |
  v             v             v             v             v             v              
Value 1       Value 2       Value 3       Value 4       Value 5       Value 6

如您所见,元素可以位于内存中的任何位置,因此您不能仅通过使用内存地址、索引和元素大小来访问第四个元素。相反,您必须从元素0开始查找元素1,然后查找元素2等,直到找到要查找的元素。

基本数据类型是更多c语言的构建块
 Element 5, other stuff, Element 3, Element 4, other stuff, Element 0, Element 2, Element 1