Java变量和运算符
Java 基础笔记:变量与运算符
本章位置:Java 核心基础
学习目标:掌握变量的定义和使用、Java 基本数据类型、类型转换,以及常见运算符的使用。
一、变量
1. 什么是变量
程序运行过程中,经常需要保存一些会发生变化的数据。
例如:
- 学生年龄
- 商品价格
- 用户积分
- 游戏血量
- 考试成绩
这些数据可以保存到变量中。
可以把变量理解成一个有名字的数据存储空间。
例如:
int age = 18;
这里:
int age = 18;
类型 变量名 数据
其中:
int:数据类型age:变量名18:变量中保存的数据=:赋值符号
二、变量的基本语法
1. 声明变量
语法:
数据类型 变量名;
例如:
int age;
这一步只是创建变量,还没有给变量赋值。
2. 给变量赋值
age = 18;
这里的 = 不是数学中的“等于”,而是赋值运算符。
意思是:
把右边的数据保存到左边的变量中。
3. 声明变量并赋值
实际开发中更常见的是:
int age = 18;
例如:
int score = 100;
double price = 19.9;
char gender = '男';
boolean login = true;
4. 修改变量中的值
变量的值是可以改变的。
int age = 18;
age = 19;
System.out.println(age);
运行结果:
19
第二次赋值会覆盖之前的数据。
三、变量的使用规则
1. 变量必须先声明,再使用
错误:
age = 18;
int age;
正确:
int age;
age = 18;
也可以:
int age = 18;
2. 局部变量使用之前必须赋值
下面代码会报错:
public class Demo {
public static void main(String[] args) {
int age;
System.out.println(age);
}
}
原因:
age 没有初始化
正确:
int age = 18;
System.out.println(age);
3. 同一个作用域中不能定义同名变量
错误:
int age = 18;
int age = 20;
会出现类似错误:
variable age is already defined
正确做法:
int age = 18;
age = 20;
4. 一个变量只能保存对应类型的数据
例如:
int age = 18;
age 是 int 类型,因此主要用于保存整数。
错误示例:
int age = "18";
字符串 "18" 不能直接保存到 int 类型变量中。
四、变量命名规则
Java 中变量名属于标识符。
1. 可以使用的字符
变量名可以由以下内容组成:
- 英文字母
- 数字
_$
例如:
int age;
int age1;
int studentAge;
int _count;
int $money;
2. 不能以数字开头
错误:
int 1age = 18;
正确:
int age1 = 18;
3. 不能使用 Java 关键字
错误:
int class = 10;
因为 class 是 Java 关键字。
常见 Java 关键字:
public
class
static
void
int
double
if
else
for
while
return
new
4. Java 严格区分大小写
下面是三个不同的变量:
int age = 18;
int Age = 20;
int AGE = 22;
虽然语法允许,但实际开发中不要这样写,否则代码非常容易看错。
五、变量命名规范
语法允许并不代表推荐这样写。
Java 变量一般采用小驼峰命名法。
单个单词
int age;
int score;
int count;
多个单词
第一个单词首字母小写,后面的单词首字母大写:
int studentAge;
double productPrice;
String userName;
int totalScore;
推荐:
int studentAge;
不推荐:
int a;
int x;
int student_age;
int StudentAge;
特殊情况下,循环计数器使用 i、j、k 很常见:
for (int i = 0; i < 10; i++) {
}
六、Java 的数据类型
Java 数据类型可以先简单分成两大类:
Java 数据类型
│
├─ 基本数据类型
│
└─ 引用数据类型
当前阶段重点学习基本数据类型。
Java 一共有 8 种基本数据类型。
七、整数类型
整数类型有四种:
| 类型 | 占用空间 | 大致范围 |
|---|---|---|
byte |
1 字节 | -128 ~ 127 |
short |
2 字节 | -32768 ~ 32767 |
int |
4 字节 | 约 -21 亿 ~ 21 亿 |
long |
8 字节 | 非常大的整数范围 |
最常用的是:
int
例如:
int age = 18;
int score = 100;
int count = 2000;
八、long 类型
如果数字超过 int 的范围,可以使用 long。
例如:
long population = 1400000000;
但是对于非常大的整数,建议在数字后面添加:
L
例如:
long number = 3000000000L;
为什么要写 L?
因为 Java 中直接写出来的整数,默认会优先按照 int 处理。
下面代码会报错:
long number = 3000000000;
正确:
long number = 3000000000L;
建议使用大写 L:
100L
不要写:
100l
因为小写 l 很容易和数字 1 混淆。
九、小数类型
Java 中常用的小数类型:
| 类型 | 占用空间 | 特点 |
|---|---|---|
float |
4 字节 | 单精度 |
double |
8 字节 | 双精度 |
开发中更常使用:
double
例如:
double price = 19.9;
double height = 175.5;
十、float 的注意事项
Java 中直接写的小数默认是:
double
因此下面代码会报错:
float price = 19.9;
需要在数字后面添加:
F
正确:
float price = 19.9F;
或者:
float price = 19.9f;
通常写:
19.9F
十一、字符类型 char
char 用于保存单个字符。
例如:
char gender = '男';
char level = 'A';
char symbol = '#';
注意:
字符必须使用:
单引号
例如:
char c = 'A';
char 和 String 的区别
字符:
char c = 'A';
字符串:
String str = "A";
区别:
'A' char,只能表示一个字符
"A" String,可以表示一串字符
例如:
String name = "张三";
String message = "Hello Java";
虽然 String 经常使用,但它并不是 Java 的 8 种基本数据类型之一。
十二、boolean 布尔类型
boolean 表示逻辑状态。
只有两个值:
true
false
例如:
boolean login = true;
boolean deleted = false;
boolean adult = true;
它经常用于后面的:
if 判断
while 循环
业务状态判断
例如:
boolean isLogin = true;
System.out.println(isLogin);
十三、8 种基本数据类型总结
| 分类 | 类型 | 示例 |
|---|---|---|
| 整数 | byte |
byte a = 10; |
| 整数 | short |
short b = 100; |
| 整数 | int |
int age = 18; |
| 整数 | long |
long num = 100L; |
| 小数 | float |
float price = 9.9F; |
| 小数 | double |
double price = 9.9; |
| 字符 | char |
char c = 'A'; |
| 布尔 | boolean |
boolean flag = true; |
实际开发初学阶段重点记住:
整数 int
大整数 long
小数 double
字符 char
真假 boolean
字符串 String
十四、字面量
直接写在代码中的数据,可以理解为字面量。
例如:
10
3.14
'A'
"Hello"
true
分别表示:
10 整数字面量
3.14 小数字面量
'A' 字符字面量
"Hello" 字符串字面量
true 布尔字面量
十五、整数的不同写法
Java 中整数可以使用不同进制表示。
十进制
int a = 10;
二进制
以 0b 开头:
int b = 0b1010;
结果也是:
10
八进制
以 0 开头:
int c = 012;
十六进制
以 0x 开头:
int d = 0xA;
这些值:
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
输出都是:
10
十六、数字中的下划线
为了让大数字更容易阅读,Java 允许使用 _ 分隔数字。
例如:
int money = 1_000_000;
等价于:
int money = 1000000;
例如:
long population = 1_400_000_000L;
这样比:
long population = 1400000000L;
更容易阅读。
十七、变量的作用域
变量并不是在整个程序中都能使用。
变量可以使用的范围称为:
作用域
例如:
public class Demo {
public static void main(String[] args) {
int age = 18;
System.out.println(age);
}
}
age 是在 main 方法内部定义的,因此主要在当前方法中使用。
再看:
public class Demo {
public static void main(String[] args) {
{
int age = 18;
System.out.println(age);
}
// System.out.println(age);
}
}
离开 {} 后,age 就不能再使用。
可以先简单记住:
变量通常只能在它所在的
{}范围内使用。
十八、常量 final
有些数据定义之后不希望再被修改。
例如:
final double PI = 3.1415926;
使用 final 修饰之后:
PI = 3.14;
会报错。
因此:
final
可以理解为:
这个变量只能赋值一次。
常量通常使用全大写命名:
final double PI = 3.1415926;
final int MAX_COUNT = 100;
十九、自动类型转换
不同的数据类型之间有时可以自动转换。
基本规律:
小范围类型 → 大范围类型
通常可以自动完成。
常见顺序可以先记成:
byte → short → int → long → float → double
char → int
例如:
int a = 10;
long b = a;
double c = b;
这是允许的。
示例
int age = 18;
double number = age;
System.out.println(number);
输出:
18.0
因为:
int → double
属于小范围向大范围转换。
二十、强制类型转换
如果要:
大范围类型 → 小范围类型
Java 不会自动转换。
需要进行:
强制类型转换
语法:
目标类型 变量名 = (目标类型) 数据;
例如:
double number = 10.8;
int result = (int) number;
System.out.println(result);
输出:
10
注意:
10.8 → 10
小数部分被直接丢掉,并不是四舍五入。
强制转换可能造成数据丢失
例如:
int number = 200;
byte result = (byte) number;
System.out.println(result);
结果并不是:
200
因为 byte 的范围只有:
-128 ~ 127
所以强制转换存在数据溢出的风险。
不要认为:
(目标类型)
只是为了消除编译错误。
它可能真的改变数据。
二十一、类型提升
进行运算时,Java 有一个很容易踩坑的规则。
byte、short、char 在参与算术运算时,通常会先提升成:
int
例如:
byte a = 10;
byte b = 20;
// byte c = a + b;
上面会报错。
因为:
a + b
运算之后的结果类型是:
int
正确写法:
int c = a + b;
或者:
byte c = (byte) (a + b);
第二种写法虽然可以,但实际开发中没有必要时不要乱做强制转换。
二十二、运算符
运算符就是对数据进行操作的符号。
例如:
10 + 20
其中:
+
就是运算符。
Java 基础阶段常见运算符:
算术运算符
赋值运算符
关系运算符
逻辑运算符
自增自减运算符
三元运算符
位运算符
移位运算符
二十三、算术运算符
常见算术运算符:
| 运算符 | 作用 |
|---|---|
+ |
加 |
- |
减 |
* |
乘 |
/ |
除 |
% |
取余 |
例如:
int a = 10;
int b = 3;
System.out.println(a + b);
System.out.println(a - b);
System.out.println(a * b);
System.out.println(a / b);
System.out.println(a % b);
输出:
13
7
30
3
1
二十四、整数除法
这是 Java 初学时非常常见的问题。
int a = 10;
int b = 3;
System.out.println(a / b);
结果:
3
不是:
3.333333
因为:
整数 / 整数 = 整数
小数部分会被舍弃。
想得到小数怎么办?
只要参与运算的数据中有一个是小数即可。
例如:
System.out.println(10.0 / 3);
或者:
int a = 10;
int b = 3;
double result = (double) a / b;
System.out.println(result);
结果:
3.3333333333333335
二十五、取余运算符 %
% 表示:
取余数
例如:
System.out.println(10 % 3);
结果:
1
因为:
10 ÷ 3 = 3 余 1
取余的常见用途
判断奇偶数
int number = 10;
System.out.println(number % 2);
如果:
number % 2 == 0
说明是偶数。
如果:
number % 2 != 0
说明是奇数。
二十六、字符串连接运算符 +
+ 除了做加法,还可以进行字符串拼接。
例如:
String name = "张三";
System.out.println("姓名:" + name);
输出:
姓名:张三
一个非常重要的例子
System.out.println(10 + 20 + "Java");
结果:
30Java
因为先计算:
10 + 20
得到:
30
然后:
30 + "Java"
进行字符串拼接。
再看:
System.out.println("Java" + 10 + 20);
结果:
Java1020
执行过程相当于:
"Java" + 10
↓
"Java10"
"Java10" + 20
↓
"Java1020"
使用括号改变运算顺序
System.out.println("结果:" + (10 + 20));
结果:
结果:30
所以拼接字符串时,需要特别注意:
+
到底是在做数学加法还是字符串拼接。
二十七、自增和自减运算符
Java 提供:
++
--
分别表示:
自增 1
自减 1
例如:
int a = 10;
a++;
System.out.println(a);
结果:
11
等价写法
a++;
可以简单理解为:
a = a + 1;
同理:
a--;
可以理解为:
a = a - 1;
二十八、前置 ++ 和后置 ++
这是考试和面试中都很容易出现的题。
有两种写法:
++a;
和:
a++;
如果单独写:
a++;
或者:
++a;
效果基本相同,都是让 a 增加 1。
但是如果参与其他运算,结果就不同。
后置 ++
int a = 10;
int b = a++;
System.out.println(a);
System.out.println(b);
输出:
11
10
可以理解为:
先使用 a 原来的值
再让 a + 1
所以:
b = 10
a = 11
口诀:
a++:先用后加
前置 ++
int a = 10;
int b = ++a;
System.out.println(a);
System.out.println(b);
输出:
11
11
可以理解为:
先让 a + 1
再使用新的值
口诀:
++a:先加后用
– 同理
a--;
--a;
分别可以理解为:
a--:先用后减
--a:先减后用
二十九、赋值运算符
最基本的赋值运算符:
=
例如:
int age = 18;
含义:
把 18 保存到 age 中
复合赋值运算符
Java 还提供:
+=
-=
*=
/=
%=
例如:
int a = 10;
a += 5;
System.out.println(a);
结果:
15
可以简单理解成:
a = a + 5;
其他例子:
int a = 10;
a -= 2;
System.out.println(a);
a *= 3;
System.out.println(a);
a /= 2;
System.out.println(a);
a %= 4;
System.out.println(a);
三十、复合赋值的隐藏类型转换
这一点比较容易忽略。
例如:
byte a = 10;
a += 5;
这是可以正常编译的。
但是:
byte a = 10;
// a = a + 5;
这里可能出现类型问题。
因为:
byte + int
运算后会提升成:
int
而:
a += 5;
内部会包含相应的类型转换处理。
因此:
a += 5;
和:
a = a + 5;
不能在所有情况下简单认为完全一样。
三十一、关系运算符
关系运算符用于比较两个数据。
结果一定是:
boolean
也就是:
true
false
常见关系运算符:
| 运算符 | 含义 |
|---|---|
> |
大于 |
< |
小于 |
>= |
大于等于 |
<= |
小于等于 |
== |
等于 |
!= |
不等于 |
例如:
int a = 10;
int b = 20;
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a == b);
System.out.println(a != b);
输出:
false
true
false
true
三十二、= 和 == 的区别
这是初学 Java 最容易犯的错误之一。
一个等号
=
表示:
赋值
例如:
int age = 18;
两个等号
==
表示:
比较
例如:
int age = 18;
System.out.println(age == 18);
结果:
true
一定要区分:
= 赋值
== 比较
三十三、逻辑运算符
逻辑运算符主要用于连接多个条件。
常见:
| 运算符 | 含义 |
|---|---|
& |
与 |
| ` | ` |
! |
非 |
^ |
异或 |
&& |
短路与 |
| ` |
实际开发中最常用:
&&
||
!
三十四、逻辑与 &&
只有左右条件都为 true,结果才是 true。
例如:
int age = 20;
boolean result = age >= 18 && age <= 60;
System.out.println(result);
相当于判断:
年龄是否大于等于 18
并且
年龄是否小于等于 60
&& 真值表
| 左边 | 右边 | 结果 |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
口诀:
全真才真
三十五、逻辑或 ||
只要其中一个条件为 true,结果就是 true。
例如:
int age = 70;
boolean result = age < 18 || age > 60;
System.out.println(result);
|| 真值表
| 左边 | 右边 | 结果 |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
口诀:
有真就真
三十六、逻辑非 !
! 表示取反。
例如:
boolean login = true;
System.out.println(!login);
结果:
false
再例如:
boolean login = false;
System.out.println(!login);
结果:
true
可以理解为:
true → false
false → true
三十七、异或 ^
异或规则:
两个条件不同 → true
两个条件相同 → false
例如:
System.out.println(true ^ true);
System.out.println(true ^ false);
System.out.println(false ^ true);
System.out.println(false ^ false);
结果:
false
true
true
false
基础开发中使用频率没有 && 和 || 高。
三十八、& 和 && 的区别
两者都可以表示逻辑与。
例如:
true & true
true && true
但是执行方式不同。
使用 &
条件1 & 条件2
无论条件1结果如何:
条件2都会执行
使用 &&
条件1 && 条件2
如果条件1已经是:
false
整个表达式一定是:
false
所以 Java 不再执行条件2。
这叫:
短路
因此:
&&
叫做:
短路与
示例
int a = 10;
int b = 0;
boolean result = b != 0 && a / b > 2;
System.out.println(result);
这里:
b != 0
结果是:
false
因此后面的:
a / b > 2
不会执行。
这样就避免了:
除数为 0
的问题。
实际开发中判断多个条件,一般优先使用:
&&
||
三十九、| 和 || 的区别
与前面的情况类似。
|
左右两边都会执行。
||
如果左边已经是:
true
整个表达式必然为:
true
右边不会继续执行。
因此 || 叫:
短路或
四十、三元运算符
语法:
条件 ? 条件成立时的结果 : 条件不成立时的结果
例如:
int age = 20;
String result = age >= 18 ? "成年人" : "未成年人";
System.out.println(result);
输出:
成年人
执行逻辑:
age >= 18
│
├─ true → "成年人"
│
└─ false → "未成年人"
求两个数最大值
int a = 10;
int b = 20;
int max = a > b ? a : b;
System.out.println(max);
输出:
20
判断奇偶数
int number = 7;
String result = number % 2 == 0 ? "偶数" : "奇数";
System.out.println(result);
结果:
奇数
四十一、位运算符
这一部分初学阶段先理解概念即可。
常见位运算符:
&
|
^
~
它们可以直接对整数的二进制位进行运算。
例如:
int a = 5;
int b = 3;
System.out.println(a & b);
先转换成二进制:
5 = 0101
3 = 0011
按位与:
0101
0011
----
0001
所以结果是:
1
按位与 &
规则:
1 & 1 = 1
其他情况 = 0
按位或 |
规则:
只要有一个 1,结果就是 1
按位异或 ^
规则:
相同为 0
不同为 1
按位取反 ~
int a = 5;
System.out.println(~a);
这一部分涉及补码,当前阶段知道作用即可,后面如果学习底层、算法或源码时再深入。
四十二、移位运算符
Java 常见移位运算符:
<<
>>
>>>
左移
int a = 5;
System.out.println(a << 1);
对于普通正整数,可以简单理解为:
左移 1 位 ≈ 乘以 2
因此:
5 << 1 = 10
右移
int a = 10;
System.out.println(a >> 1);
对于普通正整数,可以简单理解为:
右移 1 位 ≈ 除以 2
因此:
10 >> 1 = 5
>>> 是无符号右移,初学阶段先知道有这个运算符即可。
四十三、运算符优先级
Java 中不同运算符存在优先级。
例如:
int result = 10 + 20 * 3;
结果是:
70
因为先执行:
20 * 3
再执行:
10 + 60
常见优先级
不用一开始死背完整表格。
先掌握常用顺序:
()
↓
++ -- !
↓
* / %
↓
+ -
↓
> < >= <=
↓
== !=
↓
&&
↓
||
↓
? :
↓
= += -= *= /= %=
写实际代码时,如果不确定:
直接加括号
例如:
int result = (10 + 20) * 3;
这样既安全,也更容易阅读。
四十四、几个容易出错的表达式
1. 整数除法
错误理解:
double result = 10 / 3;
很多人认为结果是:
3.333...
实际上:
10 / 3
先进行整数除法,结果是:
3
然后再赋值给 double:
3.0
正确:
double result = 10.0 / 3;
或者:
double result = (double) 10 / 3;
2. 字符串拼接
System.out.println("结果:" + 10 + 20);
结果:
结果:1020
想得到:
结果:30
应该写:
System.out.println("结果:" + (10 + 20));
3. ++ 不要写得太复杂
虽然 Java 允许:
int a = 10;
int b = a++ + ++a;
但实际开发中非常不推荐这样写。
它虽然可以计算,但代码可读性非常差。
推荐拆开:
a++;
++a;
int b = ...;
学习时需要理解 ++,开发时则应该优先保证代码容易读懂。
四十五、var 局部变量类型推断
Java 10 以后支持:
var
例如:
var age = 18;
var name = "张三";
var price = 19.9;
编译器会根据右侧的数据自动推断类型。
可以理解为:
var age = 18;
编译器知道它实际上是:
int age = 18;
但是:
var
不是“没有类型”。
Java 依然是强类型语言。
var 的限制
不能这样写:
var age;
因为编译器无法知道 age 是什么类型。
必须同时初始化:
var age = 18;
初学 Java 时,建议先熟练掌握:
int
double
boolean
String
等明确类型,再使用 var。
四十六、完整练习:商品金额计算
需求:
定义商品单价和购买数量,计算总金额。
public class ProductDemo {
public static void main(String[] args) {
double price = 12.5;
int count = 3;
double total = price * count;
System.out.println("商品单价:" + price);
System.out.println("购买数量:" + count);
System.out.println("商品总价:" + total);
}
}
输出:
商品单价:12.5
购买数量:3
商品总价:37.5
这个练习涉及:
变量
int
double
*
字符串拼接
四十七、完整练习:交换两个变量
定义:
int a = 10;
int b = 20;
希望交换之后:
a = 20
b = 10
可以借助临时变量:
public class SwapDemo {
public static void main(String[] args) {
int a = 10;
int b = 20;
int temp = a;
a = b;
b = temp;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
}
输出:
a = 20
b = 10
核心过程:
原始:
a = 10
b = 20
第一步:
temp = a
temp = 10
第二步:
a = b
a = 20
第三步:
b = temp
b = 10
四十八、完整练习:判断奇偶数
目前还没有正式学习 if,因此先使用三元运算符。
public class NumberDemo {
public static void main(String[] args) {
int number = 15;
String result = number % 2 == 0
? "偶数"
: "奇数";
System.out.println(result);
}
}
运行结果:
奇数
这里涉及:
%
==
? :
这一道练习非常重要,因为下一章学习 if 时还会继续使用。
四十九、完整练习:判断年龄是否合法
假设合法年龄范围:
0 ~ 150
代码:
public class AgeDemo {
public static void main(String[] args) {
int age = 20;
boolean valid = age >= 0 && age <= 150;
System.out.println(valid);
}
}
这里:
age >= 0
判断年龄是否不小于 0。
age <= 150
判断年龄是否不大于 150。
使用:
&&
连接两个条件。
五十、综合练习
下面的练习建议自己先写,再看答案。
练习 1:个人信息
定义变量保存:
姓名
年龄
身高
是否为学生
并输出。
参考:
public class StudentDemo {
public static void main(String[] args) {
String name = "张三";
int age = 20;
double height = 175.5;
boolean student = true;
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("身高:" + height);
System.out.println("是否为学生:" + student);
}
}
练习 2:计算长方形面积
已知:
长 = 10
宽 = 5
计算面积。
public class RectangleDemo {
public static void main(String[] args) {
double length = 10;
double width = 5;
double area = length * width;
System.out.println("面积:" + area);
}
}
练习 3:计算平均分
已知三门成绩:
语文:90
数学:85
英语:95
计算平均分。
public class ScoreDemo {
public static void main(String[] args) {
int chinese = 90;
int math = 85;
int english = 95;
double average = (chinese + math + english) / 3.0;
System.out.println("平均分:" + average);
}
}
为什么使用:
3.0
而不是:
3
因为这样可以避免整数除法导致小数部分丢失。
练习 4:求两个数最大值
public class MaxDemo {
public static void main(String[] args) {
int a = 20;
int b = 35;
int max = a > b ? a : b;
System.out.println("最大值:" + max);
}
}