Java 程序设计基础之数据类型
前面我们在介绍 Java 中的字面值以及变量时提到过,Java 中的数据类型分类:基本数据类型(Primitive Type)和引用数据类型(Reference Type),本文我们来详细解读 Java 的数据类型定义以及应用,本文学习之后重新回顾之前的内容,可以帮助你更好的理解前文。
Java 中的数据类型结构如图:
下面我们分别来看两种数据类型的说明:
Java 中的基本数据类型
Java 中包含八种基本的数据类型,都是 Java 基础语言中预先定义好的。
基本数据类型包括:byte(字节型)、short(短整型)、int(整型)、long(长整型)、boolean(布尔型)、char(字符型)、float(单精度浮点型)、和 double (双精度浮点型)共 8 种。
所有的基本数据类型的大小(所占用的字节数,数据取值范围)都已明确规定,在各种不同的平台上保持不变,这一特性有助于提高 Java 程序的可移植性。
类型名称 | 关键字 | 占用内存 | 取值范围 |
---|---|---|---|
字节型 | byte | 1 字节 | -128~127 |
短整型 | short | 2 字节 | -32768~32767 |
整型 | int | 4 字节 | -2147483648~2147483647 |
长整型 | long | 8 字节 | -9223372036854775808L~9223372036854775807L |
单精度浮点型 | float | 4 字节 | +/-3.4E+38F(6~7 个有效位) |
双精度浮点型 | double | 8 字节 | +/-1.8E+308 (15 个有效位) |
字符型 | char | 2 字节 | ISO 单一字符集,也可以看作是一种整数类型,相当于无符号整数类型 |
布尔型 | boolean | 1 字节 | true 或 false |
整数类型
Java 定义了 4 种整数类型变量用于存放整型字面值:
- 字节型(byte)
- 短整型(short)
- 整型(int)
- 长整型(long)
使用说明如下:
名称 | 说明 |
---|---|
byte | byte 类型是最小的整数类型。当用户从网络或文件中处理数据流时,或者处理可能与 Java 的其他内置类型不直接兼容的未加工的二进制数据时,该类型非常有用。 |
short | short 类型限制数据的存储为先高字节,后低字节,这样在某些机器中会出错,因此该类型很少被使用。 |
int | int 类型是最常使用的一种整数类型。 |
long | 对于大型程序常会遇到很大的整数,当超出 int 类型所表示的范围时就要使用 long 类型。 |
这些都是有符号的值,具体区别在于不同类型的整型,最大值,最小值不一样,见小节开始。
如果试图给 byte 类型的变量赋予超出其范围的值(300),就会产生编译错误
1 | public class HelloWorld{ |
字符型
Java 语言中的字符类型(char)使用两个字节的 Unicode 编码表示,它支持世界上所有语言,可以使用单引号字符或者整数(0~65535)对 char 型赋值。
超过一个字符,或整数超过 65535 就会产生编译错误。
1 | public class HelloWorld{ |
前面我们知道,字符型字面值中的字符可以八进制或者十六进制,八进制使用 ‘反斜杠加3位八进制数字’ 表示,例如 ‘\141’ 表示字母 a。十六进制使用 ‘\u加上4为十六进制的数’ 表示,如 ‘\u0061’ 表示字符 a。
Java 只允许转义不超过 0377 的八进制数来表示字符。0377 是占满 8 位的数,但 Java 中的 char 是 16 位,所以无法表达所有 char 值。 其实 Java 允许转义八进制数表示字符是来源于 C 语言,C 中字符类型只占 8 位,所以才有这个限制。Java 是推荐使用转义十六进制数来表示 char 的。
如果不用转义,换一种方式,你可以用“把八进制数表示为整型,再把整型转为 char 类型”来实现八进制数到 char 的转换。用 ‘卷’ 举例,它的八进制数值为 051567,可以这样:char c = (char)051567;
Unicode 字符集(char)通常用十六进制表示,范围从\uOOOO ~ \uFFFF
,刚好占满(0~65535)。
布尔类型
布尔类型(boolean)用于对两个数值或表达式通过逻辑运算,判断结果是“真”还是“假”。
只能是取 true 和 false 这两个值中的一个。
在 Java 语言中,布尔类型的值不能转换成任何数据类型,true 常量不等于 1,而 false 常量也不等于 0。这两个值只能赋给声明为 boolean 类型的变量,或者用于布尔运算表达式中。
浮点类型
浮点类型是带有小数部分的数据类型,也叫实型。
浮点型数据包括单精度浮点型(float)和双精度浮点型(double),代表有小数精度要求的数字。
一个值要能被真正看作 float,它必须以 f(或 F)后缓结束;否则,会被当作 double 值。对 double 值来说,d(或 D)后缓是可选的。
1 | public class HelloWorld{ |
String
说起数据类型,不得不提的就是字符串类型,是使用双引号引起来的单个或多个字符。
事实上,Java 中 String 类型其实 并不是基本类型,是一个类,并且是 Immutable(不可变)类型的,一旦创建就不能够被改变。
引用类型
所谓引用数据类型就是对一个对象的引用。
引用数据类型是建立在基本数据类型的基础上,包括数组、类和接口。
Java 语言中不支持 C++ 中的指针类型、结构类型、联合类型和枚举类型。
引用类型还有一种特殊的 null 类型。因为 null 类型没有名称,所以不可能声明一个 null 类型的变量或者转换到 null 类型。
在实际开发中,程序员可以忽略 null 类型,把 null 只当作是引用类型的一个特殊字面值,用于给引用类型赋初始值,并且不要把一个 null 值赋给基本数据类型的变量。。
数据类型转换
数据类型的转换是在所赋值的数值类型和被变量接收的数据类型不一致时发生的,它需要从一种数据类型转换成另一种数据类型。也就是说,不同类型之间的数据可以互相转换。
但是要注意,满足一定的规则才可以互相转换:
精度高的数据类型就像容量大的杯子,可以放更大的数据
精度低的数据类型就像容量小的杯子,只能放更小的数据
小杯子往大杯子里倒东西,大杯子怎么都放得下
大杯子往小杯子里倒东西,有的时候放的下,有的时候就会有溢出
所以根据以上两种情况,Java 中的数据类型的转换可以分为
- 隐式转换(自动类型转换)
- 显式转换(强制类型转换)
隐式转换
自动转换规则:低精度类型向高精度类型进行转换,会进行自动转换。
这里有一个 拓宽转换(widening conversion)原则:在运算过程中,由于不同的数据类型会转换成同一种数据类型,所以整型、浮点型以及字符型都可以参与混合运算。最终结果会自动转发成高精度的字面值。
1 | public class HelloJava { |
任何运算单元的长度,超过 int,那么运算结果就按照最长的长度计算。不超过 int,那么运算结果就按照 int 来计算
自动转换规则:
- 数值型数据的转换:byte→short→int→long→float→double。
- 字符型转换为整型:char→int→long→float→double。
需要注意的是,虽然 short 和 char 都是16位的,长度是一样的,但是彼此之间,依然需要进行强制转换。byte 也不能自动转换为 char,而且 char 也不能自动转换为 byte。
这里的强制转换,就是我们下面要提到的显示转换。
– > 自动类型提升有好处,但它也会引起令人疑惑的编译错误。引发一个问题:
1 | byte b = 50; |
第二行会报 “类型不匹配:无法从int转换为byte” 错误。
该程序试图将一个完全合法的 byte 型的值 50*2 再存储给一个 byte 型的变量。但是当表达式求值的时候,操作数被自动的提升为 int 型,计算结果也被提升为 int 型。这样表达式的结果现在是 int 型,不强制转换它就不能被赋为 byte 型。
所以应该使用一个显示的强制类型转换,例如:
1 | byte b = 50; |
显示转换
当两种数据类型不兼容(byte <–> char),或目标类型的取值范围小于源类型时,自动转换将无法进行,这时就需要进行显示的强制类型转换。其语法格式如下:
1 (type)variableName
但是注意,强制转换的意思就是,转是可以转的,但是不对转换之后的值负责。 风险自担,后果自负
就像我们前面说的,大杯子往小杯子里倒东西,有的时候放的下,有的时候就会有溢出。当出现溢出时,不也就意味着数据丢失么?所以使用显示转换时要注意!!!
显示转化可使用场景如下:
install_url
to use ShareThis. Please set it in _config.yml
.