数据类型
此文章已收录至项目 Developer-Knowledge-Base
在 Java 中,一共有 8 种基本类型 (primitive type), 其中有 4 种整型、2 种浮点类型、1 种用于表示 Unicode 编码的字符 单元的字符类型 char 和 1 种用于表示真值的 boolean 类型
总览
类型 | 字节数 | bit 数 | 取指范围 | 默认值 | 包装类 |
---|---|---|---|---|---|
byte | 1 | 8 | -2^7 ~ 2^7-1 (-128 ~ 127) | 0 | Byte |
short | 2 | 16 | -2^15 ~ 2^15-1 (-32768 ~ 32767) | 0 | Short |
int | 4 | 32 | -2^31 ~ 2^31-1 (-2147483648 ~ 2147483647) | 0 | Integer |
long | 8 | 64 | -2^63 ~ 2^63-1 (-9223372036854775808 ~ 9223372036854775807) | 0 | Long |
float | 4 | 32 | -3.4e+38 ~ 3.4e+38 | 0.0f | Float |
double | 8 | 64 | -1.7e+308 ~ 1.7e+308 | 0.0d | Double |
boolean | 1/8 | 1 | true false | false | Boolean |
char | 2 | 16 | u0000uFFFF(‘’‘?’) | \u0000 | Character |
解析
整型
整型用于表示没有小数部分的数值,它允许是负数
int
,short
,long
,byte
都属于整型
其中 long
需要在最后写上字母 L
来表示这是整型,理论上不分大小写,但是若写成 "l"
容易与数字 "1"
混淆,不容易分辩。所以最好大写。
byte
类型与 short
, 主要用于节约空间,一般用于大型数组中,替代 int
类型
示例:
byte a = 0
short b = 1
int c = 1
long d = 0L
浮点型
浮点类型用于表示有小数部分的数值,在 Java 中有两种浮点类型,分别是 float
与 double
double
表示这种类型的数值精度是 float
类型的两倍 (有人称之为双精度数值)。绝大部分应用程序都采用 double
类型
float
类型需要在结尾加上字母 F
,可以不区分大小写,但为了统一还是大写比较好
由于浮点类型默认就是 double
类型,所以 double
类型末尾的 D
可加可不加,同样不区分大小写
示例:
float i = 3.14F
double j = 3.1415926
double j = 3.1415926D
字符型
java 中的一个 char 占用 2 个字节。java 采用 unicode,2 个字节来表示一个字符。一个数字或英文或汉字都是一个字符,只不过数字和英文时,存储的 2 个字节的第一个字节都为 0,就是浪费了点空间。存汉字就占满了 2 个字节。
char 类型的字面量值要用单引号括起来
因为 char 是 16 位的,采取的 Unicode 的编码方式,所以 char 就有以下的初始化方式:
char c='c';
: 单个字符,可以是汉字,因为是 Unicode 编码。需要加单引号。
char c=十进制数,八进制数,十六进制数都可以;
:可以用整数赋值【整数范围:0~65535】。输出字符编码表中对应的字符。
char c='\u数字';
:用字符的编码值来初始化,如:char=‘\0’,表示结束符,它的 ascll 码是 0,这句话的意思和 char c=0 是一个意思。
特殊字符转义序列:
转义序列 | 名称 | Unicode 值 |
---|---|---|
\b | 退格 | \u0008 |
\t | 制表符 | \u0009 |
\n | 换行 | \u000a |
\r | 回车 | \u000d |
\" | 双引号 | \u0022 |
\’ | 单引号 | \u0027 |
\\ | 反斜杠 | \u005c |
public class Hello{
public static void main(String[] args){
char a = '1';
char b = 'A';
char c = '男';//单个汉字也可以存为 char 类型
char d = '\t';//制表符相当于按 tab 键
System.out.print(a);
System.out.print(b);
System.out.print(d);
System.out.print(c);
}
}
在 Java 中对 char
进行自增或自减运算时,会得到字符之前或者之后的 Unicode 字符
char x = 'A';
System.err.println(++x); //输出 B
boolean 类型
boolean (布尔) 类型有两个值:false 和 true,用来判定逻辑条件整型值和布尔值之间不能进行相互转换,这点不同于 c 语言
boolean isJavaFun = true;
boolean isFishTasty = false;
System.out.println(isJavaFun); // 输出 true
System.out.println(isFishTasty); // 输出 false
类型转换
数据类型的转换是在所赋值的数值类型和被变量接收的数据类型不一致时发生的,它需要从一种数据类型转换成另一种数据类型。数据类型的转换可以分为隐式转换(自动类型转换)和显式转换(强制类型转换)两种。
自动类型转换 (隐式转换)
Java 基本数据类型的优先级:
当不同的数据类型进行运算时,又或者是优先级低的数据类型赋值给优先级高的数据类型时就会进行自动类型转换
在运算过程中,由于不同的数据类型会转换成同一种数据类型,所以整型、浮点型以及字符型都可以参与混合运算。自动转换的规则是从低级类型数据转换成高级类型数据
Java 中,short、byte、char 类型的数据在做运算的时候,都会默认提升为 int
例如:
byte
与short
进行运算,都将转成int
byte
或short
与 char 进行运算,都将转为int
- 由于
double
的优先级最高,所有与double
的运算都将转为double
public static void main(String[] args) {
// 这些变量名是为了直观,现实中不能这么起变量名
byte _byte = 0;
short _short = 1;
char _char = '1';
int _int = 2;
long _long = 3L;
float _float = 3.14F;
double _double = 3.1415926;
// 结果是 int 类型
System.out.println(_byte + _char);
// 结果是 int 类型
System.out.println(_byte + _short);
// 结果是 long 类型
System.out.println((_int + _long));
// 结果是 float 类型
System.out.println(_byte + _float);
// 结果是 double 类型
System.out.println(_int + _double);
}
按理说,如果一个
byte
与一个short
进行运算应该会转为两者之中优先级更高的short
才对,为何会转为int
呢,这是因为JVM
在字节码层面上支持的整数类型确实只有int
和long
,所有比int
小的整数类型都会被提升为int
来运算。因为 java 虚拟机能执行的操作码数量有限呢,最多 256 条,所以为了节省指令数目,做了这样的处理。— 在《深入了解 java 虚拟机》,虚拟机执行子系统一章中有提到。
强制类型转换 (显式转换)
原文:https://blog.csdn.net/cw616729/article/details/123024977
强制类型转换,可以理解为自动类型转换的逆过程。是将大容量的数据类型转换为小容量的数据类型。
使用时,前面要加上强制类型转换符号 ()
例如:
int a = 10;
byte b = (byte) a
强制类型转换符号
()
,只对最近的操作数有效。可以使用小括号来提升优先级。
public class ForceConvert1{
public static void main(String[] args){
//强制类型转换符号 (),只对最近的操作数有效。可以使用小括号来提升优先级。
int a = (int)(10 * 3.5 + 1.5 * 6);
int b = (int)10 * 3.5 + 1.5 * 6;//编译会报错。因为等号右边的运算结果是 double 类型,不能直接赋值给 int 型的变量 a。
System.out.println(a);
System.out.println(b);
}
}
char 类型的变量可以保存默认为 int 类型的常量(前提是常量的值在 char 类型的范围内),但是不能直接保存为 int 类型的变量值,需要进行强制类型转换。
char c1 = 100;
int a = 100;
char c2 = a;//此行程序编译会报错。
char c3 = (char)a;
使用风险
程序中使用强制类型转换,可能面临 精度损失 与 数据溢出 的风险
示例:
public class ForceConvert{
public static void main(String[] args){
//风险 1:精度降低
double a = 1.9;
int b = (int)a;
System.out.println(b);//造成精度降低,输出 1
//风险 2:数据溢出
int c = 1000;//对应二进制为 11 1110 1000
byte d = (byte)c;//强制转换为 byte 类型,直接截去 11 1110 1000 超出低 8 位的二进制,变为 1110 1000。
//因为 java 中整型都是有符号,所以 1110 1000 的最高位是符号位,为 1 则表示是一个负数。
//计算机中,正数的原码等于补码,而负数的原码不等于补码。
//计算机中,用二进制的补码来存储数据。
//所以,1110 1000 是补码,转换成原码就是 1001 1000,就是 -24。
//补码转换为原码的方法:符号位不变,从右边往左边数,第一个不是 0 的后面依次取反。
System.out.println(d);//造成数据溢出,输出 -24
}
}
判断以下哪些语句会报错。
short s = 12;//对,因为 12 在 short 类型的范围内。
s = s - 9;//报错,等号右边为 int 类型,int 类型数据不能直接赋值给 short 类型。
byte b = 10;//对,因为 10 在 byte 类型的范围内。
b = b + 11;//报错,等号右边为 int 类型,int 类型数据不能直接赋值给 byte 类型。
b = (byte)(b + 11);//对,等号右边为 int 类型,int 类型数据通过强转,赋值给 byte 类型。
char c = 'a';//对
int i = 16;//对
float d = .314F;//对
double result = c + i + d;//对,等号右边的运算结果是 float 类型,float 类型可以直接赋值给 double 类型
byte b = 16;//对
short s =14;//对
short t = s + b;//报错,等号右边的运算结果是 int 类型,int 类型不能直接赋值给 short 类型。