刚学Java就被变量和if-else绕晕了?
别急!这篇博客将用 “说人话”+代码演示 的方式,带你彻底搞懂:
int a = 10;
和 final double PI = 3.14;
有什么区别?10 / 3
结果是3而不是3.333?for
和while
循环到底用哪个?学完这篇,你写的代码将从HelloWorld
升级为能算能判能循环
的智能程序!
核心内容:
✅ 变量与常量:声明
、作用域
、final
关键字的妙用
✅ 八大数据类型:int
、double
、boolean
…选型避坑指南
✅ 运算符:算术/比较/逻辑运算符的隐藏坑点(比如==
和equals
的区别)
✅ 流程控制:if-else
、switch
、for
、while
实战场景对比
适合人群:
HelloWorld
后迷茫的新手变量是存储数据的容器,其值可以改变。
int age = 25; // 声明一个整数变量age,赋值为25
age = 26; // 修改age的值
✅ 特点:
int
、String
)数据类型 变量名 = 初始值; // 推荐:声明时初始化
数据类型 变量名; // 仅声明,不赋值(默认值取决于类型)
示例:
String name = "张三"; // 字符串
double price = 9.99; // 双精度浮点数
boolean isStudent = true; // 布尔值
_
或$
开头int
、class
)age
和Age
是不同变量)userName
)a
、b
这种无意义名称)❌ 错误示例:
int 1age; // 不能以数字开头
String class; // class是关键字
public void printAge() {
int age = 30; // 局部变量
System.out.println(age);
}
// System.out.println(age); // 报错!超出作用域
用 final
关键字声明,命名通常全大写:
final double PI = 3.1415926; // 常量PI的值不可修改
// PI = 3.14; // 报错!常量不能重新赋值
✅ 使用场景:
public class VariableDemo {
public static void main(String[] args) {
// 变量声明与赋值
int score = 90;
final String SCHOOL = "清华大学";
// 修改变量值
score = 95;
// SCHOOL = "北大"; // 报错:常量不可修改
// 打印结果
System.out.println("学校:" + SCHOOL + ",分数:" + score);
}
}
输出:
学校:清华大学,分数:95
特性 | 变量 | 常量 |
---|---|---|
关键字 | 无 | final |
可修改 | 是 | 否 |
命名 | 小驼峰(如userName ) |
全大写(如MAX_SIZE ) |
int count;
System.out.println(count); // 报错:未初始化
int x = 10;
if (x > 5) {
int y = 20;
}
System.out.println(y); // 报错:y不在作用域内
✔ 尽量在声明时初始化(避免未赋值风险)
✔ 常量用final
+全大写(提高代码可读性)
✔ 避免魔法数字:用常量替代直接数值(如MAX_USERS = 100
)
Java 是一种强类型语言,所有变量都必须明确指定数据类型。Java 的数据类型分为两大类:基本数据类型(Primitive Types) 和 引用数据类型(Reference Types)。
数据类型 | 关键字 | 大小(字节) | 默认值 | 取值范围 | 示例 |
---|---|---|---|---|---|
字节型 | byte |
1 | 0 | -128 ~ 127 | byte b = 100; |
短整型 | short |
2 | 0 | -32,768 ~ 32,767 | short s = 1000; |
整型 | int |
4 | 0 | -2³¹ ~ 2³¹-1 | int i = 100000; |
长整型 | long |
8 | 0L | -2⁶³ ~ 2⁶³-1 | long l = 10000000000L; |
单精度浮点型 | float |
4 | 0.0f | ±1.4E-45 ~ ±3.4E+38 | float f = 3.14f; |
双精度浮点型 | double |
8 | 0.0d | ±4.9E-324 ~ ±1.8E+308 | double d = 3.1415926; |
字符型 | char |
2 | ‘\u0000’ | 0 ~ 65,535(Unicode) | char c = 'A'; |
布尔型 | boolean |
1(JVM依赖) | false |
true / false |
boolean flag = true; |
适用场景:
byte
:节省内存,如文件读写、网络传输short
:较少使用,适用于特定硬件限制int
:最常用,适用于大多数整数计算long
:大整数计算(如时间戳、金融计算)示例:
byte age = 25; // 年龄(-128~127)
short year = 2024; // 年份
int salary = 100000; // 工资
long population = 8000000000L; // 全球人口(注意加L后缀)
区别:
float
:单精度(7位有效数字),节省内存double
:双精度(15位有效数字),默认推荐示例:
float pi = 3.14f; // 必须加f/F后缀
double salary = 15000.50; // 默认double,无需后缀
⚠ 注意:浮点数计算可能有精度问题(如 0.1 + 0.2 ≠ 0.3
),金融计算建议用 BigDecimal
。
''
包裹示例:
char grade = 'A'; // 成绩等级
char chinese = '中'; // 中文字符
char unicode = '\u0041'; // 'A'(Unicode编码)
true
/ false
,用于逻辑判断0
/1
互换(不同于C语言)示例:
boolean isStudent = true;
if (isStudent) {
System.out.println("享受学生折扣");
}
byte b = 100;
int i = b; // 自动转换(byte→int)
int i = 200;
byte b = (byte) i; // 强制转换(int→byte),值可能溢出!
char c = 'A';
int ascii = c; // 输出65(ASCII码)
char nextChar = (char) (ascii + 1); // 'B'
❌ 整数溢出:
int max = Integer.MAX_VALUE;
System.out.println(max + 1); // 输出-2147483648(溢出)
❌ 浮点数精度问题:
System.out.println(0.1 + 0.2); // 输出0.30000000000000004
❌ 未初始化变量:
int x;
System.out.println(x); // 编译错误:未初始化
✔ 优先用 int
和 double
(最常用)
✔ 大数用 long
,小数用 BigDecimal
(避免溢出/精度问题)
✔ 常量加后缀(long
→L
,float
→f
)
✔ 避免魔法数字(用常量代替,如 MAX_SPEED = 100
)
运算符是Java中用于执行各种计算和逻辑操作的特殊符号。
Java运算符主要分为以下几类:
运算符 | 描述 | 示例 |
---|---|---|
+ |
加法 | 3 + 2 = 5 |
- |
减法 | 5 - 2 = 3 |
* |
乘法 | 2 * 3 = 6 |
/ |
除法 | 10 / 3 = 3 (整数除法) |
% |
取模(余数) | 10 % 3 = 1 |
++ |
自增 | i++ (先使用后加1) |
-- |
自减 | --i (先减1后使用) |
示例代码:
int a = 10, b = 3;
System.out.println(a + b); // 13
System.out.println(a / b); // 3(整数除法)
System.out.println(a % b); // 1
int i = 5;
System.out.println(i++); // 5(先打印,后i=6)
System.out.println(++i); // 7(先i=7,后打印)
⚠ 注意:
用于比较两个值,返回true
或false
:
运算符 | 描述 | 示例 |
---|---|---|
== |
等于 | 5 == 5 → true |
!= |
不等于 | 5 != 3 → true |
> |
大于 | 5 > 3 → true |
< |
小于 | 5 < 3 → false |
>= |
大于等于 | 5 >= 5 → true |
<= |
小于等于 | 5 <= 3 → false |
示例代码:
int x = 10, y = 20;
System.out.println(x == y); // false
System.out.println(x != y); // true
System.out.println(x > y); // false
用于组合多个条件:
运算符 | 描述 | 示例 |
---|---|---|
&& |
逻辑与(短路) | true && false → false |
` | ` | |
! |
逻辑非 | !true → false |
& |
逻辑与(非短路) | true & false → false |
` | ` | 逻辑或(非短路) |
短路特性:
&&
:如果第一个条件为false
,不再计算第二个条件||
:如果第一个条件为true
,不再计算第二个条件示例代码:
int age = 18;
boolean isStudent = true;
// 短路与
if (age >= 18 && isStudent) {
System.out.println("成年学生");
}
// 短路或
if (age < 12 || age > 65) {
System.out.println("享受特殊优惠");
}
直接操作二进制位:
运算符 | 描述 | 示例 |
---|---|---|
& |
按位与 | 5 & 3 → 1 |
` | ` | 按位或 |
^ |
按位异或 | 5 ^ 3 → 6 |
~ |
按位取反 | ~5 → -6 |
<< |
左移 | 5 << 1 → 10 |
>> |
右移(带符号) | -5 >> 1 → -3 |
>>> |
无符号右移 | -5 >>> 1 → 2147483645 |
示例代码:
int a = 5, b = 3;
System.out.println(a & b); // 1(0101 & 0011 = 0001)
System.out.println(a << 1); // 10(左移1位相当于*2)
运算符 | 描述 | 示例 |
---|---|---|
= |
赋值 | int a = 5; |
+= |
加后赋值 | a += 3; (等价于a = a + 3 ) |
-= |
减后赋值 | a -= 2; |
*= |
乘后赋值 | a *= 4; |
/= |
除后赋值 | a /= 2; |
%= |
取模后赋值 | a %= 3; |
示例代码:
int num = 10;
num += 5; // num = 15
num /= 3; // num = 5
语法:条件 ? 表达式1 : 表达式2
如果条件为true
,返回表达式1,否则返回表达式2。
示例代码:
int score = 85;
String result = (score >= 60) ? "及格" : "不及格";
System.out.println(result); // 输出"及格"
=
和==
:if (a = 5) {} // 错误!应该是a == 5
double d = 5 / 2; // 结果是2.0,不是2.5
int x = 5 + 3 * 2; // 11,不是16
✔ 使用括号明确运算顺序:(a + b) * c
✔ 避免在复杂表达式中混合多种运算符
✔ 浮点数比较使用Math.abs(a - b) < 0.00001
代替==
// 测试你的理解:以下代码输出什么?
int x = 5;
System.out.println(x++ + ++x);
流程控制是编程中的核心概念,它决定了代码的执行顺序和逻辑分支。Java 提供了 条件语句 和 循环语句 来实现不同的控制流程。
if-else
语句语法:
if (条件1) {
// 条件1为 true 时执行
} else if (条件2) {
// 条件2为 true 时执行
} else {
// 所有条件为 false 时执行
}
示例:
int score = 85;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
✅ 适用场景:
switch-case
语句语法:
switch (变量) {
case 值1:
// 匹配值1时执行
break;
case 值2:
// 匹配值2时执行
break;
default:
// 无匹配时执行
}
示例:
int day = 3;
switch (day) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
default:
System.out.println("未知");
}
⚠ 注意:
break
防止 case 穿透(不加 break
会继续执行下一个 case
)switch
表达式(更简洁写法)for
循环语法:
for (初始化; 条件; 更新) {
// 循环体
}
示例:
for (int i = 0; i < 5; i++) {
System.out.println("当前值: " + i);
}
✅ 适用场景:
while
循环语法:
while (条件) {
// 循环体
}
示例:
int i = 0;
while (i < 5) {
System.out.println(i);
i++;
}
✅ 适用场景:
do-while
循环语法:
do {
// 循环体(至少执行一次)
} while (条件);
示例:
int i = 0;
do {
System.out.println(i);
i++;
} while (i < 5);
✅ 适用场景:
关键字 | 作用 |
---|---|
break |
退出当前循环或 switch |
continue |
跳过本次循环,进入下一次 |
return |
退出方法(可返回值) |
示例:
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // 当 i=5 时终止循环
}
if (i % 2 == 0) {
continue; // 跳过偶数
}
System.out.println(i);
}
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
int target = (int) (Math.random() * 100); // 生成随机数(0~99)
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("猜一个数(0~99): ");
int guess = scanner.nextInt();
if (guess == target) {
System.out.println("恭喜,猜对了!");
break;
} else if (guess < target) {
System.out.println("太小了!");
} else {
System.out.println("太大了!");
}
}
}
}
❌ 死循环(忘记更新循环变量):
while (i < 5) { // 如果 i 不更新,会无限循环
System.out.println(i);
}
❌ switch
漏写 break
:
switch (day) {
case 1:
System.out.println("星期一");
// 漏掉 break,会继续执行 case 2
case 2:
System.out.println("星期二");
break;
}
数组是Java中用于存储固定数量、相同类型数据的数据结构。
✅ 固定长度:创建后大小不可变
✅ 相同类型:所有元素必须是同一数据类型
✅ 索引访问:通过下标(从 0
开始)快速访问元素
// 方式1:先声明,后初始化
int[] nums1; // 推荐写法
int nums2[]; // 兼容C风格(不推荐)
// 方式2:声明时直接初始化
int[] nums3 = {1, 2, 3}; // 静态初始化
int[] nums4 = new int[5]; // 动态初始化(默认值:0)
String[] names = new String[]{"A", "B"}; // 显式指定大小
int[] nums = {10, 20, 30};
System.out.println(nums[0]); // 输出:10(第一个元素)
nums[1] = 99; // 修改第二个元素为99
⚠ 注意:越界访问会抛出 ArrayIndexOutOfBoundsException
!
System.out.println(nums[3]); // 错误!有效索引是0~2
int len = nums.length; // 返回3(不是方法,是属性)
方法1:for
循环
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
方法2:for-each
循环(只读)
for (int num : nums) {
System.out.println(num);
}
方法3:Arrays.toString()
import java.util.Arrays;
System.out.println(Arrays.toString(nums)); // 输出:[10, 20, 30]
// 声明与初始化
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
// 访问元素
System.out.println(matrix[1][2]); // 输出:6(第二行第三列)
// 遍历
for (int[] row : matrix) {
for (int num : row) {
System.out.print(num + " ");
}
System.out.println();
}
int[][] jagged = new int[3][];
jagged[0] = new int[]{1};
jagged[1] = new int[]{2, 3};
jagged[2] = new int[]{4, 5, 6};
java.util.Arrays
)方法 | 作用 | 示例 |
---|---|---|
sort() |
排序 | Arrays.sort(nums); |
binarySearch() |
二分查找 | Arrays.binarySearch(nums, 20); |
fill() |
填充值 | Arrays.fill(nums, 0); |
copyOf() |
复制数组 | int[] copy = Arrays.copyOf(nums, 2); |
equals() |
比较数组 | Arrays.equals(arr1, arr2); |
示例:
int[] nums = {3, 1, 2};
Arrays.sort(nums); // 变为 [1, 2, 3]
int index = Arrays.binarySearch(nums, 2); // 返回1
❌ 越界访问
int[] arr = new int[3];
System.out.println(arr[3]); // 抛出ArrayIndexOutOfBoundsException
❌ 未初始化直接使用
int[] arr;
System.out.println(arr[0]); // 编译错误:未初始化
❌ 混淆数组长度与字符串长度
int len = arr.length; // 数组用属性
String s = "Hi";
int strLen = s.length(); // 字符串用方法
int[] nums = {5, 2, 9, 1};
int max = nums[0];
for (int num : nums) {
if (num > max) max = num;
}
System.out.println("最大值:" + max); // 输出9
int[] nums = {1, 2, 3};
for (int i = 0; i < nums.length / 2; i++) {
int temp = nums[i];
nums[i] = nums[nums.length - 1 - i];
nums[nums.length - 1 - i] = temp;
}
System.out.println(Arrays.toString(nums)); // 输出 [3, 2, 1]
“恭喜!你现在已经掌握了Java的‘骨骼系统’!
接下来可以:
最后送大家一句话:
编程就像搭乐高,先把基础积木摸透,才能造出炫酷的城堡~
PS:如果你在学习过程中遇到问题,别慌!欢迎在评论区留言,我会尽力帮你解决!