是否有充分的理由在64位JVM中使用short而不是int?
我的意思是,两者都需要分配32位内存。
本主题说明Integer如何更快地进行乘法等运算:
[在Java中,使用byte或short代替int和float代替double效率更高?
我也知道原始数组最好用于节省分配的内存。
除此之外,在这两种类型之间进行选择时还需要考虑其他因素吗?
您是在谈论Integer和Short对象还是关于Short和int基本值? 您没有一直使用它们。
TL;博士
除非您有一个非常特殊的用例,否则请使用:
Integer用于表示业务对象的值,即类上的成员变量。
int用于大量原始数据。
只需使用Integer
对于大多数常见的面向业务的Java应用程序,通常的做法是仅使用32位int或Integer而不作进一步考虑,除非您知道自己的价值将超过20亿,在这种情况下,请使用long或< X5>。在现代常规硬件上,几乎没有理由烦恼使用short / short。
特别案例
但是,由于您询问"在选择时还有其他需要考虑的因素",因此这里有三种特殊情况:强制限制,移植C代码和替代硬件。
强制执行限制
如果要强制short或short的限制,请使用这些类型。当您知道应该只有大约小于32,000的值并且希望编译器或运行时JVM强制使用该值时,请选择这些值。
例如,将101加一:
short oneOhOnePlusOne = ( (short) 101 + (short) 1 ) ;
System.out.println("oneOhOnePlusOne:" + oneOhOnePlusOne ) ;
102
接下来,尝试超过限制以查看编译器强制执行该限制。
short shortMaxPlusOne = ( Short.MAX_VALUE + (short) 1 ) ;
System.out.println("shortMaxPlusOne:" + shortMaxPlusOne ) ;
error: incompatible types: possible lossy conversion from int to short
看到此代码在IdeOne.com上实时运行。
移植C代码
这些各种数字类型可能已放入Java中,以使移植C代码变得更容易,无论是从实践上还是从心理上都更加容易。 Java的发明者深知,在那个时代,大多数尝试使用新编程语言的尝试都因批评"它不像C"而失败。因此就是Objective-C(Java的灵感),也就是C ++的怪癖。
因此,确实,如果要移植C代码,请使用匹配类型来复制行为。
顺便说一下...从技术上讲,C实际上并未定义其数字类型的大小。实际上,实际上,每种C实现都使用Java中看到的大小。
仅供参考,即使是最现代的语言,例如Swift和Kotlin,也都具有用于8、16、32和64位整数的内置数字类型。
更具限制性的硬件
如果您的应用程序有可能在不基于x86-64的其他硬件上运行,那么您可能要使用这些类型。针对此类硬件的Java替代实现可能会针对较小的类型进行更好的优化。
原始对象与对象
Array of primitives are preferable for saving memory allocated
首先,不要强调这一点。不要陷入过早优化的陷阱。在具有大多数常用应用程序的常规硬件上,使用原语,对象,数组和集合所节省的内存将微不足道。使用适合您的编码上下文的类型(原始/对象)和结构(数组/集合)。
我的做法:
在我的代码中,对象。
仅在我自己的类中使用对象(Integer,而不是int)。我有两个原因。首先,我属于希望Java是纯OOP而没有任何原语的Object迷。 (实际上,正在进行研究,以查看基元是否可以在遥远的Java版本中实际上消失。)其次,我发现当我使用基元时,最终需要在需要上下文的对象(例如集合)中使用它。
在其他人的代码中,请使用原语。
在我自己的类之外,我不强迫这样做,因为过度的自动装箱是毫无意义的。如果外部代码(不是我自己的代码)使用基元,那么我将在该上下文中使用基元。
@Thilo我举起您的文字,以tl;dr开头。谢谢。
@Thilo,因为OP触及了他的问题中的"数组",所以int的数组和Integer的数组实际上可能会比看起来有更大的影响。例如读取pdf作为字节数组。对于重要的pdf,每个Byte都会添加一个额外的24 bytes;否则必须同意您的意见。
@Eugene我根据您的评论扩展了tl; dr部分。
通常,@ Thilo批量数据处理是原始数据的领域,无论库是处理byte[],ByteBuffer,InputStream / OutputStream还是IntStream。我认为将它们都称为"特殊情况"是没有意义的。而且,我还是不明白。即使我们假定情况没有相关的性能差异,为什么我还要使用更长的Integer,在键入时需要使用Shift键,并要求我考虑是否可能是null?为什么要使用" Integer代表业务价值"?我在这里没有看到任何原因。
不幸的是,@ Holger我们使用它。我们的团队认为null确实是"尚未编写"的,因为int默认情况下可以为零,并且在我们的案例中零具有商业价值。我承认可以用更好的方法来完成,但这是一个待办事项多年,从未执行过的待办事项
@Eugene,这就是我所说的特例。但是,您可以将TODO推迟到Java真正支持可空基元类型(例如int?等)之前。