跳转到内容

基本数据类型

100% developed
来自 Wikibooks,开放世界中的开放书籍

浏览 语言基础 主题:v  d  e )


基本类型是 Java 语言中最基本的数据类型。共有 8 种:booleanbytecharshortintlongfloatdouble。这些类型是 Java 中数据操作的基础。这些类型只服务于一个目的 - 包含纯粹的、简单的某种类型的值。因为这些数据类型在 Java 类型系统中默认定义,所以它们附带了许多预定义的操作。你无法为这些基本类型定义新的操作。在 Java 类型系统中,还有三种基本类型的类别。

  • 数值基本类型:shortintlongfloatdouble。这些基本数据类型只保存数值数据。与这些数据类型相关的操作是简单算术(加、减等)或比较(大于、等于等)。
  • 文本基本类型:bytechar。这些基本数据类型保存字符(可以是Unicode 字母表甚至数字)。与这些类型相关的操作是文本操作(比较两个单词、连接字符构成单词等)。但是,bytechar 也可以支持算术运算。
  • 布尔和空基本类型:booleannull

所有基本类型都有固定大小。因此,基本类型的值范围有限。较小的基本类型(byte)可以包含的值比更大的类型(long)少。

类别 类型 大小(位) 最小值 最大值 精度 示例
整数 byte 8 -128 127 从 +127 到 -128 byte b = 65;
char 16 0 216-1 所有 Unicode 字符[1] char c = 'A';
char c = 65;
short 16 -215 215-1 从 +32,767 到 -32,768 short s = 65;
int 32 -231 231-1 从 +2,147,483,647 到 -2,147,483,648 int i = 65;
long 64 -263 263-1 从 +9,223,372,036,854,775,807 到 -9,223,372,036,854,775,808 long l = 65L;
浮点型 float 32 2-149 (2-2-23)·2127 从 3.402,823,5 E+38 到 1.4 E-45 float f = 65f;
double 64 2-1074 (2-2-52)·21023 从 1.797,693,134,862,315,7 E+308 到 4.9 E-324 double d = 65.55;
其他 boolean -- -- -- false, true boolean b = true;
void -- -- -- -- --

整数基本类型会静默溢出

Example 代码部分 3.52:几个运算符。
int i = Integer.MAX_VALUE;
System.out.println(i);
i = i + 1;
System.out.println(i);
System.out.println(Integer.MIN_VALUE);
Computer code 代码部分 3.52 的控制台
2147483647
-2147483648
-2147483648

由于 Java 是强类型语言,因此不能将浮点数(带小数点的数字)赋值给整型变量

Warning 代码部分 3.53:将浮点数设置为 int(整型)类型的值。
int age;
age = 10.5;

基本类型应通过适当的值设置。基本类型可以用字面量初始化。大多数字面量都是基本类型的值,除了字符串字面量,它们是 String 类的实例。

计算机科学中的数字

[编辑 | 编辑源代码]

编程可能不再像以前那样只是处理大量的数字,既不平凡也不无聊。然而,如今任何编程语言(更不用说 Java)中编写的代码的大部分都在痴迷地处理数字,无论是生成巨大的素数[2],还是仅仅计算你的踏板车排放的成本。1965 年,双子座五号 太空任务险些因编程错误而发生致命事故[3]。1979 年,一个计算机程序高估了五个核反应堆抵抗地震的能力;这些工厂暂时关闭[4]。这两个编程错误都有一个共同点:错误发生时正在计算的主题数据是数值的。从过去的经验来看,Java 带来了针对数值数据的改进的类型检查,并非常重视正确识别其不同类型。在编程方面,你必须认识到数值数据的意义。

数字使用二进制系统存储在内存中。内存就像一个单元格网格

                               

每个单元格可以包含一个二进制数字(简称为),也就是说,零或一

 0   1   1   0   0   1   0   1 

实际上,每个单元格确实包含一个二进制数字,因为一位大约相当于1,而内存中的空单元格表示0。单个二进制数字只能保存两种可能的值:零或一。

内存状态 给出
                             0  0
                             1  1

多个位组合在一起可以保存多个排列 - 2 位可以保存 4 种可能的值,3 位可以保存 8 种,依此类推。例如,8 位可以保存的最大数字(二进制中的11111111)在十进制系统中是255。因此,从 0 到 255 的数字可以放入 8 位中。

内存状态 给出
 0   0   0   0   0   0   0   0  0
 0   0   0   0   0   0   0   1  1
 0   0   0   0   0   0   1   0  2
 0   0   0   0   0   0   1   1  3

...
...
 1   1   1   1   1   1   1   1  255

一切都很好,但这样我们只能保存正数(或无符号整数)。它们被称为无符号整数。无符号整数是所有为正的整数值,不归因于负值。出于这个原因,我们会要求 8 位中的一个位保存有关数字符号(正数或负数)的信息。这使我们只剩下 7 位来实际计算一个数字。这 7 位可以保存的最大数字(1111111)在十进制系统中是127

正数

内存状态 给出
 0   0   0   0   0   0   0   0  0
 0   0   0   0   0   0   0   1  1
 0   0   0   0   0   0   1   0  2
 0   0   0   0   0   0   1   1  3

...

...
...
 0   1   1   1   1   1   1   1  127


负数

内存状态 给出
 1   0   0   0   0   0   0   0  -128
 1   0   0   0   0   0   0   1  -127
 1   0   0   0   0   0   1   0  -126
 1   0   0   0   0   0   1   1  -125

...

...
...
 1   1   1   1   1   1   1   1  -1


总之,使用这种方法,8 位可以保存从-128127(包括零)的数字 - 共 256 个数字。有人可能会认为,这不算太糟糕。与无符号整数相反的是有符号整数,它能够保存正值和负值。

但是,较大的数字怎么办?你需要更多的位来保存更大的数字。这就是 Java 的数值类型发挥作用的地方。Java 有多种数值类型 - 它们的尺寸取决于参与的位数。

在 Java 中,数字使用专门用于保存数值数据的类型进行处理。但在深入研究这些类型之前,我们必须首先确定一些概念。就像你在高中(甚至小学)做的那样,Java 中的数字被放置在明显不同的组和系统中。你可能已经知道,数字系统包括整数(0、1、2 ... ∞);负整数(0、-1、-2 ... -∞)甚至实数有理数圆周率值、¾、0.333~ 等)。Java 只是倾向于将这些数字分成两组,整数(-∞ ... 0 ... ∞)和浮点数(任何带有小数点或分数表示的数字)。目前,我们只关注整数值,因为它们更容易理解和使用。

Java 中的整型

[编辑 | 编辑源代码]

通过我们迄今为止学到的知识,我们将识别出在 Java 中可以创建和操作的不同类型有符号整数。以下是最基本数值类型:整数的表格。正如我们之前讨论过的,Java 中用于整数的数据类型既可以容纳正值也可以容纳负值,因此它们是 **有符号数值类型**。数值类型的大小以位为单位,它决定了该类型的最小值和最大值。如有疑问,您始终可以计算这些值。

让我们看看这些新发现的 Java 中基本整数类型的知识如何融入整体。假设您想对一年中的天数进行数值操作——所有 365 天。您会使用哪种类型?由于数据类型 `byte` 仅能达到 127,您是否愿意冒着赋予它大于其允许最大值的风险?此类决定可能会让您免受可能因编程代码而产生的可怕错误的困扰。对于此类数值操作,更明智的选择可能是 `short`。现在,为什么他们不能只制作一种数据类型来保存所有类型的数字呢?让我们来探讨一下原因。

当您告诉程序您需要使用一个整数,比如甚至是一个 `byte` 时,Java 程序会在内存中分配一个空间。它会分配 8 位的完整内存。尽管对于拥有近 12 万亿个此类位的存储模块而言,这似乎并不重要,但在其他情况下却很重要。一旦分配,该部分内存就会被使用,并且只有在操作完成后才能收回。考虑一个复杂的 Java 程序,其中您唯一使用的数据类型是 `long` 整数。当没有空间进行更多内存分配作业时会发生什么?您听说过 **堆栈溢出错误** 吗?这就是确切发生的事情——您的内存会被完全使用,而且速度很快。因此,请务必谨慎选择数据类型。

说够了,让我们看看如何创建数值类型。数值类型以类型的名称开头(`short`、`int` 等),然后为内存中分配的空间提供一个名称。以下是操作方式。假设我们需要创建一个变量来保存一年中的天数。

Example 代码部分 3.54:一年中的天数。
short daysInYear = 365;

这里,`daysInYear` 是变量的名称,它保存 `365` 作为其值,而 `short` 是该特定值的类型。Java 中整数数据类型的其他用途可能需要您编写如下所示的代码

Example 代码部分 3.55:Java 中的整数数据类型。
byte maxByte = 127;
short maxShort = 32767;
int maxInt = 2147483647;
long maxLong = 9223372036854775807L;

整数和浮点数

[edit | edit source]

可以用于整数的数据类型是 `byte`、`short`、`int` 和 `long`,但是当涉及浮点数时,我们使用 `float` 或 `double`。现在我们知道了这一点,我们可以修改 代码部分 3.53 中的代码,如下所示

Example 代码部分 3.56:正确的浮点声明和赋值。
double age = 10.5;

为什么不是 `float`,您问?如果我们使用 `float`,则必须在数字末尾添加一个 `f` 作为后缀,因此 `10.5` 应该是 `10.5f`,如下所示

Example 代码部分 3.57:定义类型为 `float` 的浮点数的正确方法。
float age = 10.5f;

浮点数学永远不会抛出异常。将非零值除以 `0` 等于 `infinity`。将非无穷值除以 `infinity` 等于 `0`。

测试您的知识

**问题 3.7:**考虑以下代码

Example 问题 3.7:基本类型赋值。
...

a = false;
b = 3.2;
c = 35;
d = -93485L;
e = 'q';

这些是五个变量。有一个 `long`、一个 `byte`、一个 `char`、一个 `double` 和一个 `boolean`。获取每个变量的类型。

答案
Example 答案 3.7:基本类型赋值和声明。
boolean a;
double b;
byte c;
long d;
char e;

a = false;
b = 3.2;
c = 35;
d = -93485L;
e = 'q';
  • `a` 只能是 `boolean`,因为只有布尔类型可以处理布尔值。
  • `e` 只能是 `char`,因为只有字符类型可以包含一个字符。
  • `b` 只能是 `double`,因为只有双精度类型可以包含此处的十进制数。
  • `d` 是 `long`,因为 `byte` 无法包含如此小的值。
  • `c` 是剩下的一个,所以它是 `byte`。

数据转换(强制转换)

[edit | edit source]

数据转换(强制转换)可以在两种基本类型之间进行。强制转换有两种类型

  • 隐式:不需要强制转换操作;数值的大小始终保持不变。但是,从整数类型转换为浮点类型时,可能会丢失 *精度*。
  • 显式:需要强制转换操作;数值的大小可能无法保持不变。
Example **代码部分 3.58:隐式强制转换(int 转换为 long,不需要强制转换)。**
int  i = 65;
long l = i;
Example **代码部分 3.59:显式强制转换(long 转换为 int,需要强制转换)。**
long l = 656666L;
int  i = (int) l;

下表显示了基本类型之间的转换,它显示了显式转换的强制转换操作

byte char short int long float double boolean
byte - (byte) (byte) (byte) (byte) (byte) (byte) N/A
char - (char) (char) (char) (char) (char) N/A
short (short) - (short) (short) (short) (short) N/A
int - (int) (int) (int) N/A
long - (long) (long) N/A
float - (float) N/A
double - N/A
boolean N/A N/A N/A N/A N/A N/A N/A -

与 C、C++ 和类似语言不同,Java 无法将 `false` 表示为 `0` 或 `null`,也无法将 `true` 表示为非零。Java 无法从布尔类型转换为非布尔基本数据类型,反之亦然。


对于非基本类型

到 Integer 到 Float 到 Double 到 String 到 Array
整数 - (float)x (double)x
x.doubleValue()
x.toString()
Float.toString(x)
new int[] {x}
Float java.text.DecimalFormat("#").format(x) - (double)x x.toString() new float[] {x}
Double java.text.DecimalFormat("#").format(x) java.text.DecimalFormat("#").format(x) - x.toString() new double[] {x}
String Integer.parseInt(x) Float.parseFloat(x) Double.parseDouble(x) - new String[] {x}
Array x[0] x[0] x[0] Arrays.toString(x) -

注释

[edit | edit source]
  1. 根据 "STR01-J. Do not assume that a Java char fully represents a Unicode code point". Carnegie Mellon University - Software Engineering Institute. Retrieved 27 Nov 2018., 并非所有 Unicode 字符都适合 16 位表示。
  2. 截至编辑(2013 年 12 月 11 日),互联网梅森素数大搜索 项目迄今为止已将最大的素数识别为 17,425,170 位。素数对于密码学家来说很有价值,因为数字越大,他们就可以使用该特定数字使其数据加密逻辑更安全。
  3. 由于软件错误,双子座5号飞船在太平洋预定着陆点以西 130 公里处着陆。 地球自转速度被编程为每太阳日旋转一周,而不是正确的每恒星日旋转一周。
  4. 他们设计中使用的程序使用了变量的算术和,而应该使用它们的绝对值的和。(Evars Witt,“小电脑和大问题”,美联社新闻,1979 年 3 月 16 日。另见 Peter Neumann,“关于软件正确性和社会过程的社论”软件工程笔记,第 4 卷(2),1979 年 4 月,第 3 页)


华夏公益教科书