为什么Java API使用int而不是短字节或字节?
为什么Java API使用,什么时候甚至就足够了?int
short
byte
示例:类“日历”
中的“DAY_OF_WEEK
”字段使用 。int
如果差异太小,那么为什么这些数据类型(,)存在呢?short
int
为什么Java API使用,什么时候甚至就足够了?int
short
byte
示例:类“日历”
中的“DAY_OF_WEEK
”字段使用 。int
如果差异太小,那么为什么这些数据类型(,)存在呢?short
int
一些原因已经指出。例如,“...(几乎)所有对字节的操作,short都会将这些原语提升为int”。但是,显而易见的下一个问题是:为什么这些类型被提升为?int
因此,更深入一层:答案可能只是与Java虚拟机指令集有关。正如 Java 虚拟机规范中的表中总结的那样,所有整型算术运算(如加法、除法等)仅适用于类型和类型,而不适用于较小的类型。int
long
(顺便说一句:较小的类型(字节
和短
)基本上只适用于数组。像 new byte[1000]
这样的数组需要 1000 个字节,而像 new int[1000]
这样的数组需要 4000 个字节。
当然,现在可以说“...显而易见的下一个问题是:为什么这些指令只针对int
(和long
)提供?
上面提到的JVM规范中提到了一个原因:
如果每个类型化指令都支持 Java 虚拟机的所有运行时数据类型,则指令将超过一个字节所能表示的指令。
此外,Java 虚拟机可以被视为真实处理器的抽象。为较小的类型引入专用的算术逻辑单元也不值得:它需要额外的晶体管,但它仍然只能在一个时钟周期内执行一个加法。设计JVM时的主要架构是32位,正好适合32位 。(涉及 64 位值的操作作为特例实现)。int
long
(注意:最后一段有点过于简单,考虑到可能的矢量化等,但应该给出基本的想法,而不必深入到处理器设计主题中)
编辑:一个简短的附录,侧重于问题中的示例,但在更一般的意义上:人们也可以问,使用较小的类型存储字段是否无益。例如,人们可能认为可以通过存储为 .但是在这里,Java类文件格式开始发挥作用:类文件中的所有字段至少占用一个“插槽”,其大小为一(32位)。(“宽”字段和 占用两个槽)。因此,显式声明字段为或不保存任何内存。Calendar.DAY_OF_WEEK
byte
int
double
long
short
byte
(几乎)上的所有操作都会将它们提升为 ,例如,您不能编写:byte
short
int
short x = 1;
short y = 2;
short z = x + y; //error
算术在使用时更容易和直接,无需转换。int
就空间而言,它几乎没有什么区别。 而且会使事情复杂化,我认为这种微优化不值得,因为我们谈论的是固定数量的变量。byte
short
byte
当您为嵌入式设备编程或处理文件/网络时,它是相关且有用的。此外,这些基元是有限的,如果计算将来可能超过其限制怎么办?试着考虑一个类的扩展,它可能会演变成更大的数字。Calendar
另请注意,在 64 位处理器中,局部变量将保存在寄存器中,并且不会使用任何资源,因此使用 和其他基元根本不会有任何区别。此外,许多 Java 实现对齐变量*(和对象)。int
short
*byte
并占用与局部变量,类变量甚至实例变量相同的空间。为什么?因为在(大多数)计算机系统中,变量地址是对齐的,所以例如,如果你使用一个字节,你实际上最终会得到两个字节 - 一个用于变量本身,另一个用于填充。short
int
另一方面,在数组中,取1个字节,取2个字节,取4个字节,因为在数组中,只有开头和结尾必须对齐。例如,如果您想要使用,这将有所作为,那么您确实会注意到性能差异。byte
short
int
System.arraycopy()