Java数据类型
正如前一章节所解释的那样,Java中的每个变量都有一个数据类型。数据类型分为两种:
- 原始数据类型
- 对象引用
一个变量占用一定的内存空间。变量占用了多少内存取决于其数据类型。
原始数据类型的变量所占用的内存中的包含了赋给该变量的数据值。例如,一个数字或一个字符。
对象引用类型的变量不同于基本类型的变量。对象类型的变量也称为引用。变量本身不包含对象,但包含对该对象的引用。该引用指向内存中的其他位置,该位置才是整个对象存放的实际内存空间。通过存储在变量中的这个引用,你可以去访问它引用的对象,如字段和方法等。多个不同的变量可以引用同一个对象,这一点对于原始数据类型是不可能办到的。
原始数据类型
Java语言包含以下基本数据类型:
数据类型 | 描述 |
---|---|
boolean(布尔型) | 二进制值,只能是 true或 false |
byte(字节型) | 8位有符号值,值从-128到127 |
short(短整型) | 16位有符号值,值从-32,768到32,767 |
char(字符型) | 16位的Unicode字符 |
int(整型) | 32位有符号值,取值范围是-2,147,483,648 ~ 2,147,483,647 |
long(长整型) | 64位有符号值,取值范围是-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,808 |
float(浮点型) | 32位浮点值 |
double(双精度浮点型) | 64位浮点值 |
这些是基本的数据类型,也就是说它们不是对象,也不是对象的引用(在后面的文章中会具体解释类和对象)。
下面是一个如何声明基本类型变量的例子:
int myInt;
对象类型
原始类型也有相应的对象。这意味着你可以通过对象引用来引用它们,你可以对相同的值给予多个引用,并且你可以像Java中的任何其他对象一样调用它们。下面是核心基本数据类型对应的对象类型。 该列表还包含了Java中其他一些核心对象类型。
数据类型 | 描述 |
---|---|
Boolean(布尔型) | 二进制值,只能是 true或 false |
Byte(字节型) | 8位有符号值,值从-128到127 |
Short(短整型) | 16位有符号值,值从-32,768到32,767 |
Character(字符型) | 16位的Unicode字符 |
Integer(整型) | 32位有符号值,取值范围是-2,147,483,648 ~ 2,147,483,647 |
Long(长整型) | 64位有符号值,取值范围是-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,808 |
Float(浮点型) | 32位浮点值 |
Double(双精度浮点型) | 64位浮点值 |
String | N字节文本数据的Unicode字符串。是不可变的 |
请注意,对象类型的名字首字母是大写的,而原始数据类型(非对象)是小写的。两者之间也有缩写差异,如 int与 Integer,char和 Character。
当然在Java API中可以使用许多其他组件,但是上面提到的数据类型是核心Java类型。而 String类型将会在Java字符串详细讲解。
你也可以通过创建自定义类来创建更复杂的数据类型。以后的教程中会有详细讲解。
下面例子声明了一个核心对象类型的引用变量:
Integer myInteger;
在声明对象引用变量时,引用不指向任何对象。你需要先创建(实例化)一个对象。就想下面例子一样:
Integer myInteger;
myInteger = new Integer(45);
在这个例子中,myInteger变量引用一个 Integer对象,其内部存储着数字45。其中代码 new Integer(45)就是创建了该 Integer对象。
你也可以在声明变量时创建对象:
Integer myInteger = new Integer(45);
原始数据类型的对象版本是不可变的
原始数据类型的对象版本是不可变的,换句话说,存储在其中的值一旦赋值了就不能改变。例如,一旦创建了对象,存储在 Integer对象中的值就不能被修改。
已经引用了一个对象的变量可以指向另一个对象。例如:
Integer myInteger = new Integer(45);
myInteger = new Integer(33);
上面例子中的变量指向另一个 Integer对象。
自动装箱
在Java 5之前,你必须调用原始类型的对象版本的方法,然后才能获取到它们的基本类型值。例如:
Integer myInteger = new Integer(45);
int myInt = myInteger.intValue();
从Java 5开始,有一个叫做“自动装箱”的概念。这意味着如果需要的话,Java可以自动地将原始变量“封装”成对象版本,或者如果需要的话,Java也可以从对象版本中将原始数据“解封装”出来。例如,之前的例子可以这样写:
Integer myInteger = new Integer(45);
int myInt = myInteger;
在这个例子中,Java会自动从 myInteger对象中提取 int值,并将该值赋值给 myInt。
同样,可以手动创建一个原始数据类型的对象版本:
int myInt = 45;
Integer myInteger = new Integer(myInt);
有了Java的“自动装箱”后,你可以这样写代码:
int myInt = 45;
Integer myInteger = myInt;
然后,Java会自动将相应类型的对象版本中的原始数据类型“组装起来”。
Java的“自动装箱”功能使你可以在需要数据类型的对象版本时使用原始数据类型,反之亦然。有一个陷阱,但要记住。对象类型的变量(对对象的引用)可以指向 null(空),这意味着它没有指向任何对象。如果你尝试将 null转换为原始值,你将得到一个 NullPointerException(一个导致程序失败的错误)。例如:
Integer myInteger = null;
int myInt = myInteger;
这段代码编译时不会有问题,但是在执行时会导致 NullPointerException,因为变量 myInteger指向 null。因此不可能转换(unbox)它所指向的对象的值,因为它不指向任何对象。
下一篇: Java数学运算符和Math类