JavaSE3️⃣程序基础 - 变量&数据类型&运算
需要了解的计算机基础知识:👉 存储单位 & 数值表示
- 存储单位:
- bit(位):描述电脑数据量的最小单位。
- byte(字节):计算机内存的最小存储单位(1byte = 8bit)。
- 数值表示:需了解计算机中正负数的表示——符号位(最高位 0 正 1 负)
1、变量
1.1、说明
- 类型:分为基本变量、引用变量。
- 使用:先定义(声明)后使用。
- 声明时可以赋初始值,声明后可以重新赋值。
- 可以赋常量值,也可以赋变量。
1.2、示例分析
针对以下代码,分析 JVM 执行操作。
// 定义变量
int x;
int y = 1;
// 修改变量值
x = 10;
y = x;
-
int x;
-
代码含义:定义变量 x,没有显式赋值(但 int 类型默认值 0);
-
JVM 操作:分配一个存储单元,变量 x 指向该存储单元。
x │ ▼ ┌───┬───┬───┬───┬───┬───┬───┐ │ │ 0 │ │ │ │ │ │ └───┴───┴───┴───┴───┴───┴───┘
-
-
int y = 1;
-
代码含义:定义变量 y,赋值 1;
-
JVM 操作:分配一个存储单元,变量 y 指向该存储单元。
x y │ │ ▼ ▼ ┌───┬───┬───┬───┬───┬───┬───┐ │ │ 0 │ │ 1 │ │ │ │ └───┴───┴───┴───┴───┴───┴───┘
-
-
x = 10;
-
代码含义:将变量 x 的值赋为 10;
-
JVM 操作:找到变量 x 的存储单元,移除原来的值 0,放入新的值10。
x y │ │ ▼ ▼ ┌───┬────┬───┬───┬───┬───┬───┐ │ │ 10 │ │ 1 │ │ │ │ └───┴────┴───┴───┴───┴───┴───┘
-
-
y = x;
-
代码含义:将变量 y 的值赋为变量 x 的值。
-
JVM 操作:找到变量 y 的存储单元,移除原来的值 1,放入新的值 10(还包含查找 x = 10 的过程)。
x y │ │ ▼ ▼ ┌───┬────┬───┬────┬───┬───┬───┐ │ │ 10 │ │ 10 │ │ │ │ └───┴────┴───┴────┴───┴───┴───┘
-
2、数据类型
2.1、基本类型
2.1.1、八大类型
基本数据类型:CPU 可直接进行运算的类型。
含义 | 内存(byte) | 范围 | 默认值 | |
---|---|---|---|---|
byte | 字节 | 1 | [-27 , 27 -1] | 0 |
short | 短整型 | 2 | [-215, 215 - 1] | 0 |
int | 整型 | 4 | [-231, 231 - 1] | 0 |
long | 长整型 | 8 | [-263, 263 - 1] | 0 |
float | 单精度浮点型 | 4 | [1.4 * 10-45, 3.4 * 1038] | 0.0 |
double | 双精度浮点型 | 8 | [4.9 * 10-324, 1.79 * 10308] | 0.0 |
char | 字符 | 2 | [0, 216 - 1] | '' |
boolean | 布尔 | 理论 1bit,实际通常 4byte | false |
2.1.2、示例
-
整数类型:
// byte byte num1 = -100; // short short num2 = 300; // int int num3 = 200_000_000; // long:赋值需要以 L 结尾 long num4 = 1L;
-
浮点数类型:
// float:赋值需要以 F 结尾 float num5 = -1.0F; // double double num6 = 3.14;
-
字符型与布尔型:
// char:以单引号赋值,即使是空字符 char ch1 = 'A'; char ch2 = '好'; char ch3 = ''; // boolean boolean flag = true; boolean isGreater = 10 > 9;
2.2、引用类型
除了八大基本类型,其它都是引用类型(如 String 字符串类型)。
引用类型的两个重要概念是变量和示例。
-
变量:存放在栈中,内部存储了对象实例在堆中的内存地址。
-
实例:存放在堆中。
// 格式 引用类型 变量名 = new 对象实例(); // 示例 Object obj = new Object();
2.3、说明
2.3.1、字符
char(character):字符,基本类型。
- 变量形式:单引号
''
包围。 - 底层实现:Java 使用 Unicode 表示中/英文字符,一个
char
占用 2 个字节。
相关操作
-
赋值整数:将
char
值赋值给整数变量,值为char
值对应的十进制 Unicode 编码。char ch1 = 'A'; char ch2 = '好'; int num1 = ch1; // 65 int num2 = ch2; // 22909
-
Unicode 表示:可用转义字符
\u
结合十六进制 Unicode 编码表示字符。char ch1 = '\u0041'; // A char ch2 = '\u597D'; // 好
2.3.2、常量
常量:需要显式初始化,并且无法再次赋值,否则报错。
- 定义:定义变量时使用
final
修饰符。 - 作用:提前声明变量名,以此避免在代码中使用魔法值(Magic Number)。
2.3.3、作用域
概念
- 语句块:Java 中使用
{}
包围语句块,作为一组完整代码(如类、方法、控制语句)。 - 作用域:从变量的声明位置开始,到变量所在语句块结束。
最佳实践
- 尽量将变量的作用域最小化。
- 避免使用重复的变量名。
2.3.4、var
var 关键字:省略变量类型,由编译器自动推断。
// 示例
var sb = new StringBuilder();
// 编译器自动推断为以下语句
StringBuilder sb = new StringBuilder();
3、运算
3.1、整数运算
整数:表示的是精确的数,其运算结果也是精确的整数。
3.1.1、基本运算符
-
运算符:加
+
,减-
,乘*
,除/
,取余%
。-
除法
/
结果取整数部分,取余%
结果取余数部分。 -
除数若为
0
,编译通过但运行时报错。java.lang.ArithmeticException: / by zero
-
-
运算符简写:
-
符号:
+=
,-=
,*=
,/=
,%=
。 -
使用:
x += 10; // 等价于 x = x + 10;
-
-
自增/自减:本质也是运算符简写。
-
符号:
++
,--
。 -
使用:符号可以在变量之前或之后,其位置表示自增的顺序,会影响运算结果。
-
符号在前:先自增,后引用。
-
符号在后:先引用,后自增。
int x = 1; int y = 2; // 情况1:y先自增成3,后引用;x=3+10=13 x = ++y + 10; // 情况2:先引用y,x=2+10=12;后y自增成3 x = y++ + 10;
-
-
3.1.2、特殊运算符
① 移位运算
将十进制整数对应的二进制数进行移动。
-
左移:
<<
-
右移:
>>
(符号位不会移动) -
无符号右移:
>>>
(符号位也移动,高位自动补 0)// 右移 int n = -536870912; // 11100000 00000000 00000000 00000000 = -536870912 int a = n >> 1; // 11110000 00000000 00000000 00000000 = -268435456 int b = n >> 2; // 11111000 00000000 00000000 00000000 = -134217728 int c = n >> 28; // 11111111 11111111 11111111 11111110 = -2 int d = n >> 29; // 11111111 11111111 11111111 11111111 = -1 // 无符号右移 int n = -536870912; // 11100000 00000000 00000000 00000000 = -536870912 int a = n >>> 1; // 01110000 00000000 00000000 00000000 = 1879048192 int b = n >>> 2; // 00111000 00000000 00000000 00000000 = 939524096 int c = n >>> 29; // 00000000 00000000 00000000 00000111 = 7 int d = n >>> 31; // 00000000 00000000 00000000 00000001 = 1 // 对byte和short进行位移时,会先转换为int // 本质:左移即 * 2,右移即 / 2
② 位运算
将整数对应的二进制数按位对齐,依次运算。
也称按位运算。
- 与:全 1 才 1。
- 或:有 1 则 1。
- 非:01 互换。
- 异或:同 0 异 1。
3.1.3、说明
① 运算符优先级
()
:优先级最高,可用来改变运算顺序,提高可读性。!
~
++
--
*
/
%
+
-
<<
>>
>>>
&
|
+=
-=
*=
/=
%=
② 溢出
溢出:若运算结果超过了整数范围,不会报错,但会导致溢出。
- 原因:程序将十进制整数转换为二进制进行运算,当运算结果超过范围时,最高位从 0 变成 1,导致符号改变。
- 解决方案:改用更大范围的整数类型,如 int 改成 long。
③ 类型转换
-
类型自动提升:若参与运算的两个数类型不一致,较小类型自动提升为较大类型。
short num1 = 1; int num2 = 10; // short先自动转型为int,再参与运算 System.out.println(num1 + num2);
-
强制转型:使用
(类型)
,较大类型强制转为较小类型(可能产生错误结果)。// 正确 int num1 = 10; short num2 = (short) num1; // 10 // 错误:num1超出short范围,强制转型时丢弃2个高位字节 int num1 = 12345678; short num2 = (short) num1; // 24910
3.2、浮点数运算
浮点数:通常无法精确表示,其运算结果也是如此。
3.2.1、运算符
整数 | 浮点数 | |
---|---|---|
四则运算 | ✔ | ✔ |
取余 | ✔ | ❌ |
运算符简写 | ✔ | ✔(不包含 %= ) |
自增/自减 | ✔ | ✔ |
移位运算 | ✔ | ❌ |
位运算 | ✔ | ❌ |
3.2.2、说明
① 误差
-
由于浮点数无法精确表示,因此容易产生误差。
double num1 = 1.0 / 10; double num2 = 1 - 9.0 / 10; // 观察x和y是否相等 System.out.println(x); System.out.println(y);
-
由于误差的存在,判断浮点数是否相等的依据是两数之差小于一个很小的数(而不是使用
=
)。// 二者之差的绝对值 double diff = Math.abs(x - y); if (r < 0.00001) { // 认为相等 }
② 溢出
-
结论:整数运算
/ 0
会报错,浮点数运算/ 0
不会报错。 -
原因:IEEE-754 规定浮点数
/0
结果需要是NaN
(Not a Number)或Infinity
(无穷大)。// Java中浮点数/0的三种情况 double num1 = 0.0/0; // NaN double num2 = 1.0/0; // Infinity double num2 = -1.0/0 // -Infinity
③ 类型转换
-
类型自动提升:整数与浮点数参与同一则运算时,整数通常会自动转型为浮点型。
// 情况1:num自动转型 int num = 1; System.out.println(24.1 / num); // int自动转为double,再参与运算 // 情况2:num1不会自动转型 int num1 = 20, num2 = 4; System.out.println(3.4 + num1 / num2); // num1和num2整数运算得5,5会自动转型为double
-
强制转型:浮点数可以强制转型为整数。
-
向下取整:强制转型时,浮点数的小数部分会被丢弃。
-
四舍五入:强制转型之前,对浮点数加上 0.5 即可实现四舍五入的效果。
-
若转型后超出整型的最大范围,将返回该整型的最大值。
// 丢弃小数部分 int n1 = (int) -3.4; // -3 int n2 = (int) 5.7; // 5 // 四舍五入:转型前+0.5 int n3 = (int) (5.7 + 0.5); // 6 // 超出范围:自动返回最大值 int n4 = (int) 1.2e20; // 2147483647
-
3.3、布尔运算
布尔运算:一种关系运算,结果只有 true 和 false。
3.3.1、运算符
-
比较运算符:
>
,>=
,<
,<=
,==
,!=
-
逻辑运算符:
-
与:
&
,&&
-
或:
|
,||
-
非:
!
boolean flag1 = 1 > 2; // false boolean flag2 = 2 >= 1; // true boolean flag3 = flag1 && flag2; // false boolean flag4 = flag1 || flag2; // true boolean flag5 = !flag4; // false
-
-
三目运算符:根据布尔表达式的结果,返回后续两个表达式之一的计算结果。
-
格式:
布尔表达式 ? 表达式1 : 表达式2
-
示例:
// 取两数中的最大值 int num1 = 20; int num2 = 10; int result = num1 >= num2 ? num1 : num2;
-
3.3.2、短路运算
短路运算:若布尔运算的表达式能提前确定结果,则不会判断后续条件,直接返回结果。
-
短路运算符:
&&
,||
-
优点:提高性能。
// 非短路运算:计算后面的表达式时报错 boolean result1 = false & (7 / 0 > 1); // 短路运算:第一个false可确定结果为false,直接返回结果,不会报错 boolean result2 = false && (7 / 0 > 1);
3.3.3、运算符优先级
!
>
,>=
,<
,<=
==
,!=
&&
||
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律