Java中一共有8中基本数据类型,此外还有很多引用数据,它们如下图所示:
注意:Java当中的整数没有所谓的无符号(unsigned)类型,统一都是有符号的。
下面定义一个整型变量:
int num = 10;
注意事项:
int类型的大小和表示范围
在Java中,一个int类型的变量占4个字节(即32个bit位)和操作系统没有直接关系,这充分说明了Java的可移植性强。4个字节表示的数据范围是[-2^31, +2^31-1]
:
使用以下代码查看Java中的int数据范围:
// 输出:2147483647
System.out.println(Integer.MAX_VALUE);
// 输出:2147483648
System.out.println(Integer.MIN_VALUE);
PS:Integer是int的包装类,相当于int的puls版本。
21亿这样的数字对于当前的大数据时代来说,是很容易超出的,针对这种情况,我们就需要使用更大范围的数据类型来表示。Java中提供了long类型。
下面定义三个长整型变量:
// long类型变量的值有以下三种写法
long num1 = 10;
long num2 = 10L;
long num3 = 10l;
注意事项:
long类型的大小和表示范围
Java中long类型占8个字节,表示的数据范围[-2^63, +2^63-1]
,使用以下代码查看Java中长整型的数据范围:
// 输出:9223372036854775807
System.out.println(Long.MAX_VALUE);
// 输出:-9223372036854775808
System.out.println(Long.MIN_VALUE);
这个数据范围远超过int的表示范围,足够绝大部分的工程场景使用。
只占一个字节的byte类型只能表示整数;注意和C/C++中的char区分开,char表示出来的是字符。
byte num = 1;
注意事项:
[-128, +127]
。和C/C++一样,Java中也有short类型。
short num = 10;
注意事项:
[-32768,+32767]
。浮点数类型有两种:float、double,它们能表示的精度不一样,后者要大一些。
double a = 1.0;
double b = 2.0;
System.out.println(a / b);// 0.5
Java中的double是8个字节,但实际上浮点数的内存布局和整数差别很大,我们看下面这段代码:
double num = 1.1;
// 输出 1.2100000000000002
System.out.println(num * num);
Java中double类型的内存布局遵守IEEE 754
标准(和C语言一样),尝试使用有限的内存空间表示可能的无限小数,这势必会存在一定的精度误差,所以不能单纯地用2^n形式表示来表示浮点数的数据范围。
float类型在Java中占4个字节,同样遵守IEEE 754
标准。由于表示的数据精度范围较小,一般在工程上用到浮点数都优先考虑double,不推荐使用 float。
float num = 1.1f;// 写作1.1F也可以,但不能不写
注意:float类型的变量在初始化给值时一定要加上f或F的标识。不然会报错:java: 不兼容的类型: 从double转换到float可能会有损失
,因为在Java中浮点数字面常量值的类型默认是double(8字节)的,如果直接把它赋值给float(4字节)变量会有数据损失。
char ch = 'A';
// 打印字符A的三种方法
System.out.println(ch);// 通过char类型变量来打印
System.out.println('A');// 通过字符的字面常量来打印
System.out.println((char)65);// 通过'A'的Unicode码来表示
注意事项:
单引号 + 单个字母
的形式表示字符的字面常量。和上面的类型不同,String不是基本类型,而是引用类型。Java中使用双引号 + 若干字符
的方式表示字符串常量值:
相当于C++中的bool类型,在Java中叫做boolean,不过二者还是有区别的。
boolean flag = true;
注意事项:
硬性规则(必须遵守):
软性规则(建议遵守):
Java作为一个强类型编程语言,当不同类型之间的变量相互赋值的时候, 会进行较严格的校验,先看以下几个代码场景:
场景一:int 和 long/double 相互赋值
int a = 10;
long b = 20;
a = b; // 编译出错,提示可能会损失精度
b = a; // 编译通过
int a = 10;
double b = 1.0;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.
分析:
结论:不同数字类型的变量之间赋值:精度可以扩大但不能缩小,即使类型改变了也要尽可能的地保护数据安全。
场景二:int 和 boolean 相互赋值
int a = 10;
boolean b = true;
b = a; // 编译出错, 提示不兼容的类型
a = b; // 编译出错, 提示不兼容的类型
结论:int和boolean是毫不相干的两种类型,二者不能相互赋值。
场景三:整型字面值常量给 byte 赋值
// PS: 1、byte表示的数据范围是[-128, +127]
// 2、256已经超过了byte的范围, 而100还在范围之内
byte a = 100; // 编译通过
byte b = 256; // 编译报错, 提示:从int转换到byte可能会有损失
结论:使用字面值常量赋值的时候,Java会自动进行一些检查校验,判定赋值是否合理:
创建四:使用强制类型转换
int a = 0;
double b = 10.5;
a = (int)b;// 编译通过
int a = 10;
boolean b = false;
b = (boolean)a; // 编译出错, 提示不兼容的类型
结论:
类型转换小结
不同数字类型的变量在运算时会发生数值提升,具体看下面两个场景:
场景一:int 和 long 混合运算
int a = 10;
long b = 20;
int c = a + b; // 编译出错,提示将long转成int会丢失精度
long d = a + b;// 编译通过
分析:
类型提升小结
int转成String:利用String包装类的valueOf()
方法,即可返回一个String类型的由整数转化而来的字符串,注意 valueOf 中的O是大写的。
int num = 10;
String s = String.valueOf(num);
String转成int:利用Integer包装类的parseInt()
方法,把需要转化的字符串作为参数传入即可,注意 parseInt 中的I是大写的。
String s = "10";
int num = Integer.parseInt(s);
小结:对标C++中的转换
PS:运算符之间是有优先级的,我们不需要去记忆谁的优先级高或低,只需根据自己的逻辑加上括号即可。
关系运算符主要有六个:> < >= <= == !=
,注意关系运算符的表达式返回值都是boolean类型。
int a = 10;
int b = 20;
System.out.println(a == b);// false
System.out.println(a != b);// true
System.out.println(a < b); // true
System.out.println(a > b); // false
System.out.println(a <= b);// true
System.out.println(a >= b);// false
逻辑运算符主要有三个:&& || !
,注意逻辑运算符的操作数(操作数往往是关系运算符的结果)和返回值都是boolean。
逻辑与 &&:全true才true,都则为false,这是个双目运算符
// 对于&&,如果左侧表达式值为false,
// 则表达式的整体的值一定是false,无需计算右侧表达式
System.out.println((10 > 20) && (10/0 == 0));// 打印 false
逻辑或 ||:全flase才false,否则为true,这是个双目运算符
// 对于||,如果左侧表达式值为true
// 则表达式的整体的值一定是true, 无需计算右侧表达式
System.out.println((10 < 20) || (10 / 0 == 0));// 打印 true
逻辑非 !:操作数为true,结果为false;操作数为false,结果为true(这是个单目运算符,只有一个操作数)
int a = 10;
int b = 20;
System.out.println(!(a < b));// fasle
位运算符主要有四个:& | ~ ^
。Java中对数据操作的最小单位不是字节, 而是二进制位,而位操作表示的就是按二进制位运算。
计算机内部都是使用二进制来存储和表示数据的(即01构成的序列), 位运算就是在按照二进制位的每一位依次进行计算。
按位与 &:这是个双目运算符。两个二进制位中有0则结果为0,都是1结果才为1。
按位或 |:这是个双目运算符。两个二进制位中有1则为1,都是0结果才为0。
按位取反 ~:这是个单目运算符,运算规则如下:
移位运算符有三个:<< >> >>>
,它们都是按照二进制位来运算的。
右移 >>:最右侧位不要了,最左侧补符号位(正数补0,负数补1)
无符号右移 >>>:最右侧位不要了,最左侧不论正负数,统一都补0
移位运算符小结
条件运算符只有一个,也是Java中唯一的一个三目运算符。其格式如下:
表达式1 ? 表达式2 : 表达式3
注释是为了让代码更容易被读懂而附加的描述信息。不参与编译运行,但是却非常重要。
时刻牢记!代码写出来是为了给人看的,更是为了给三个月后的你自己看的。
Java中的注释主要分为以下三种: