Java中long、double、byte和char的作用是什么?

47

我正在学习Java,有个问题。似乎类型intbooleanstring可以涵盖我在变量方面所需的几乎所有内容,除了在数字中需要小数时,可能需要使用float

我的问题是,其他类型如longdoublebytechar等是否在正常的日常编程中使用?这些类型有哪些实际的用途?它们存在的目的是什么?


9
我想知道为什么这个问题被踩了?这似乎是一个合理的问题,不一定容易通过谷歌搜索得到答案。 - Ben
7个回答

116

除了可能是有点浪费空间的"short"外,它们都各有所长:

  • 当您不需要小数部分且没有理由使用其他类型时,请使用int;在大多数处理器/操作系统配置上,这是机器能够高效处理的数字大小;
  • 当您需要小数部分且没有理由使用其他类型时,请使用double
  • 当您想要表示字符(或可能需要二字节无符号算术的罕见情况)时,请使用char
  • 如果您需要明确操纵一个有符号字节(很少出现!)或者需要移动一块字节,请使用byte
  • 当您需要一个简单的“是/否”标志时,请使用boolean
  • 当您需要一个整数,但其数量级可以超过20亿(文件大小、毫秒/纳秒时间测量以及高级用途中将几个数据压缩到一个数字中),请使用long
  • 在以下两种罕见情况下,请使用float:(a)存储了大量的浮点数并且内存节省是值得的,或者(b)执行了大量的计算,并且可以承受精度损失。对于大多数应用程序,“float”的精度非常低,但操作速度可以快两倍 - 但是值得在您的处理器上测试一下,以确定是否实际上是这种情况![*]
  • 如果您确实需要2字节的有符号算术,请使用short。这种情况并不多...

[*] 例如,在Pentium架构中的Hotspot上,float和double操作通常需要完全相同的时间,除了除法之外。

不要过于纠结这些类型的内存使用,除非你真的理解它。例如:

  • 热点(Hotspot)中每个对象的大小都会舍入到16个字节,因此具有单个字节字段的对象将占用与具有长或双精度字段的单个对象完全相同的空间;
  • 当向方法传递参数时,每种类型在堆栈上占用4或8个字节:通过将方法参数从int更改为short并不能节省任何空间!(我见过有人这样做...)

显然,某些API调用(例如对于某些原因需要浮点数的非CPU密集型任务的各种调用)必须按照其要求传递类型...!

请注意,String 不是基本类型,因此它不属于此列表。


1
请注意,如果您使用的所有字符都在Unicode的基本多语言平面(BMP)内,则char仅表示一个字符。一旦您离开BMP,Java中的字符处理就会变得非常奇怪。如果您只处理西方语言,则不一定需要关心它,但您应该意识到这一点。 - sleske
请参考以下问题和答案的解释:https://dev59.com/N3E85IYBdhLWcg3w8IbK - sleske
我所能想到的byteshort原语的唯一优点是编译器允许它们直接存储在byte[]short[]数组中,而不需要类型转换。还有其他优点吗? - supercat
(或者在极少数情况下,您需要使用双字节无符号算术)什么? - JohnMerlino

19

Java中的int类型是32位,而long类型是64位,因此当您需要表示大于2^31的整数时,可以使用long类型。典型的使用long类型的示例是System.currentTimeMillis()。

字节是8位,是现代大多数硬件上可寻址的最小实体,因此在从文件读取二进制数据时需要使用它。

double类型的大小是float类型的两倍,因此通常会使用double类型而不是float类型,除非您有一些大小或速度方面的限制,并且float类型具有足够的容量。

short类型为2个字节,即16位。在我看来,这是最不必要的数据类型,我在实际代码中并没有真正看到它的使用,但是它可能用于读取二进制文件格式或执行低级网络协议。例如IP端口号是16位。

char类型表示单个字符,其大小为16位。这与short类型的大小相同,但是short类型为有符号的(-32768到32767),而char类型为无符号的(0到65535)。 (这意味着IP端口号可能比short类型更正确地表示为char类型,但这似乎超出了char类型的预期范围...)

有关这些详细信息的真正权威来源,请参见Java语言规范


整个short被标记为signed,而char被标记为unsigned的事情真的让我很烦恼。请Java先生,给我回来我的int类型的“unsigned”修饰符吧! :-) - Brian Knoblauch
Brian:我更喜欢将byte、short和char设为非数字类型。最好也将int和long设为非数字类型,并使用一个合理的任意大小的有理整数来表示数字。 - Tom Hawtin - tackline
短整型的一个用例是数组。如果您需要在内存中处理大量数字,并且知道它们都适合16位,则可以使用short[]而不是int[],从而节省50%的RAM。http://www.crazysquirrel.com/computing/java/speed_and_memory/short-array-vs-int-array.jspx - markusk

3

关于Java中的原始类型,您可以在这里查看。

这些类型之间的主要区别在于内存使用。例如,int使用32位,而byte只使用8位。

想象一下,如果您在处理大型结构(如数组、矩阵等),那么最好注意您正在使用的类型,以便减少内存使用。


3
我猜这种类型有几个目的:
1)它们对可以存储在其中的变量的大小(和符号)施加限制。
2)它们可以为代码增加一点清晰度(例如,如果您使用char,则任何阅读代码的人都知道您计划在其中存储什么)。
3)它们可以节省内存。如果您有一个大型数字数组,所有数字都是无符号且低于256,则可以将其声明为字节数组,与声明int数组相比,可以节省一些内存。
4)如果您需要存储的数字大于2 ^ 32,则需要long,如果需要存储非常大的浮点数,则需要double。

请修正关于需要使用双精度浮点数来表示大于2^32的数字的问题。 - David Schmitt
抱歉,出了点问题。现在已经修复了。 - Ben
双精度对于精确值更有用,大小并不那么重要。第一点应该是“隐藏溢出错误”:)。 - Tom Hawtin - tackline

0

整数通常用于表示数字。
双精度浮点数是用来表示小数的基本数据类型。
字符串可以存储任何数据类型,但最好仅使用整数,除非是要表示文本内容以外,否则会很容易混淆。
字符仅用于存储单个字母,虽然它们本质上只是为了明确表达意思而存在。
短整型、长整型和浮点数可能并不一定需要,但如果您需要创建一个大小为1,00000的数组,且该数组仅需要存储小于1,000的数字,则最好使用短整型,以便节省空间。


0
原始数据类型是必需的,因为它们是每个复杂集合的基础。
如果您只需要一个小整数(或其他),则使用long、double、byte等,这样不会浪费堆空间。
我知道,在我们这个时代有足够的RAM,但您不应该浪费它。
我需要“小型”的数据类型来进行数据库和流操作。

-1

这与你处理的数据有关。当你只处理少量数据时,使用保留大部分内存的数据类型是没有意义的。例如,许多数据类型在使用之前就会预留内存。以数组为例,即使你只使用其中的4个字节,它们也会默认保留一定数量的内存(比如256字节<--仅为示例!)。

请查看此链接获取答案


1
我在提问之前阅读了这篇文章,但是没有理解,所以就给它点了踩。 - Ali
数组的开销不应该如此之大。应该在16字节左右。 - Tom Hawtin - tackline

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