Java 数据类型
变量
变量用于在内存中保存程序运行期间可能发生变化的数据。
定义变量
定义变量时需要指定数据类型和变量名,也可以同时赋初始值。
int age = 20;
double price;
建议在变量首次使用前完成初始化。
变量的作用域
变量必须先定义后使用。局部变量的作用域从声明位置开始,到它所在的语句块结束。同一作用域内不能重复定义同名局部变量。
public static void main(String[] args) {
{
int age = 20;
System.out.println(age);
// double age = 0; // 同一作用域内重复定义,编译错误
}
{
double age = 0;
System.out.println(age);
}
}常量
使用 final 修饰的变量只能赋值一次,通常称为常量。
final double PI = 3.1415926;
数字、字符和字符串等直接写在代码中的值称为字面量,例如 10、'A' 和 "Java"。
数据类型分类
Java 数据类型分为基本数据类型和引用数据类型。基本数据类型直接表示简单值;数组、类、接口和枚举等属于引用数据类型。
基本数据类型
整数类型
| 类型 | 存储空间 | 取值范围 |
|---|---|---|
byte | 1 字节(8 bit) | -128 ~ 127 |
short | 2 字节(16 bit) | -2^15 ~ 2^15 - 1 |
int | 4 字节(32 bit) | -2^31 ~ 2^31 - 1 |
long | 8 字节(64 bit) | -2^63 ~ 2^63 - 1 |
整数字面量默认是 int 类型。超出 int 范围的整数字面量必须在末尾添加 L 或 l,实际开发中建议使用更清晰的 L。
int age = 20;
long population = 3_000_000_000L;
当整数范围超过 long 时,可以根据业务需要使用 BigInteger。
浮点类型
| 类型 | 存储空间 | 说明 |
|---|---|---|
float | 4 字节(32 bit) | 单精度浮点数,约 7 位十进制有效数字 |
double | 8 字节(64 bit) | 双精度浮点数,约 15~16 位十进制有效数字 |
浮点字面量默认是 double 类型。给 float 变量赋浮点字面量时,需要添加 F 或 f 后缀。
float score = 3.14F;
double price = 3.1423424;
浮点数存在精度误差。需要精确十进制运算时,应使用 BigDecimal。
字符类型
char 占两个字节,用于保存一个 UTF-16 代码单元。字符字面量使用单引号。
char letter = 'a';
char unicodeLetter = '\u0061';
常见转义字符如下:
| 转义字符 | 含义 |
|---|---|
\r | 回车 |
\n | 换行 |
\t | 制表符 |
\\ | 反斜杠 |
\" | 双引号 |
\' | 单引号 |
System.out.println("\\a\\");
System.out.println("d:\\lesson\\java2601");
System.out.println("这两个字符串\"相等\"");
布尔类型
boolean 只有 true 和 false 两个值,主要用于条件判断。Java 语言规范没有规定普通 boolean 变量必须占用多少字节,因此不应依赖其具体存储大小。
boolean passed = true;
运算符
算术运算符
常见算术运算符包括 +、-、*、/、%、++ 和 --。
前置自增先修改变量,再产生表达式结果;后置自增先产生原值,再修改变量。
int i = 3;
int j = i++;
System.out.println(j); // 3
System.out.println(i); // 4
复杂表达式中同时多次修改同一个变量会降低可读性,应尽量拆分为多条语句。
赋值运算符
赋值运算符包括 =、+=、-=、*=、/= 和 %= 等。
int value = 3;
value += 2;
复合赋值运算符会隐式执行必要的类型转换,但仍要注意可能发生的数据截断。
比较运算符
比较运算符包括 ==、!=、>、<、>= 和 <=,表达式结果为 boolean。
逻辑运算符
逻辑运算符用于处理布尔值。
!表示逻辑非。&&表示短路与。||表示短路或。
int value = 3;
System.out.println(value > 0 && value < 10);
短路运算会根据左侧结果决定是否继续计算右侧表达式。
位运算符
位运算直接对整数的二进制位进行处理。
| 运算符 | 含义 |
|---|---|
~ | 按位取反 |
& | 按位与 |
| ` | ` |
^ | 按位异或 |
<< | 左移 |
>> | 有符号右移 |
>>> | 无符号右移 |
<< 左移时右侧补零;>> 右移时左侧补符号位;>>> 右移时左侧补零。
System.out.println(-1 >>> 1);
System.out.println(~(-1 >>> 1));
对于未发生溢出的整数,左移 n 位通常等价于乘以 2^n。右移与除法在负数和舍入规则上可能存在差异,不能在所有场景中直接等同。
短路运算与按位运算
&& 和 || 只能用于布尔表达式并具有短路特性。& 和 | 既可以用于整数位运算,也可以用于布尔运算;用于布尔运算时两侧表达式都会执行。
int i = 3;
System.out.println(i > 5 && i++ < 10);
System.out.println(i); // 3
System.out.println(i > 5 & i++ < 10);
System.out.println(i); // 4
异或运算
按位异或中,相同位的结果为 0,不同位的结果为 1。
System.out.println(3 ^ 5); // 6
异或可以在不使用临时变量的情况下交换两个整数,但这种写法可读性差,并且两个变量引用同一存储位置时会出错。实际开发中建议使用临时变量。
int a = 3;
int b = 4;
int temp = a;
a = b;
b = temp;
位运算的常见应用
判断奇偶
boolean odd = (value & 1) == 1;
乘以二的幂
在不溢出的前提下,value << n 相当于 value * 2^n。
对二的幂取模
当 value 为非负整数,且除数是 2^n 时,value % 2^n 可以写成 value & (2^n - 1)。普通业务代码仍应优先选择语义更清晰的写法。
避免平均值溢出
计算两个整数的平均值时,直接使用 (x + y) / 2 可能在加法阶段溢出。可以根据取值范围使用 x + (y - x) / 2,或先转换为更大范围的类型。
运算符优先级
不确定运算顺序时,应使用括号明确表达意图,而不是依赖记忆复杂的优先级规则。
boolean result = (a + b) > 10 && c != 0;
数据类型转换
自动类型转换
取值范围较小的数值类型通常可以自动转换为取值范围较大的类型。
byte -> short -> int -> long -> float -> double
char -> int -> long -> float -> double
System.out.println(5.0 / 2); // 2.5
System.out.println('a' + 1); // 98
System.out.println(2.0 % 5); // 2.0
整数除以零会抛出 ArithmeticException;浮点数除以 0.0 可能得到无穷大或非数字结果。
System.out.println(17.0 / 0.0); // Infinity
强制类型转换
把取值范围较大的类型转换为较小的类型时,需要显式强制转换。强制转换可能造成精度损失或数值溢出。
System.out.println((int) 5.9); // 5
System.out.println((char) ('a' + 1)); // b
除 boolean 外,基本数值类型之间可以按照规则转换。编写代码时应尽量避免没有必要的强制转换,并检查转换后的取值范围。
喜欢的话,留下你的评论吧~