Java 基础语法
1.1 八大数据类型
| 类型 | 大小 | 范围 |
|---|
本文全面介绍 Java 基础语法,包括八大数据类型、运算符、流程控制、数组操作、方法定义、面向对象编程(封装、继承、多态、接口)、核心 API(String、集合、日期时间)及异常处理。内容涵盖内存模型、泛型、枚举等高级特性,并通过学生管理系统实战案例展示综合应用,辅以调试技巧与常见错误排查指南,帮助读者构建扎实的 Java 知识体系。

| 类型 | 大小 | 范围 |
|---|
| 默认值 |
|---|
| 示例 |
|---|
| byte | 8 位 | -128~127 | 0 | byte b = 100; |
| short | 16 位 | -32768~32767 | 0 | short s = 1000; |
| int | 32 位 | -2³¹~2³¹-1 | 0 | int i = 100000; |
| long | 64 位 | -2⁶³~2⁶³-1 | 0L | long l = 100L; |
| float | 32 位 | ±3.4E+38 | 0.0f | float f = 3.14f; |
| double | 64 位 | ±1.7E+308 | 0.0 | double d = 3.14; |
| char | 16 位 | 0~65535 | '\u0000' | char c = 'A'; |
| boolean | 1 位 | true/false | false | boolean flag = true; |
内存图解:
int x = 10; // 栈内存中分配 4 字节,存储值 10
double y = 3.14; // 栈内存中分配 8 字节,存储值 3.14
String s = "Hello"; // 栈存引用,堆存"Hello"字符串对象
int a = 10, b = 3; // 基本运算
System.out.println(a + b); // 13 → 加法
System.out.println(a - b); // 7 → 减法
System.out.println(a * b); // 30 → 乘法
System.out.println(a / b); // 3 → 整数除法(取整)
System.out.println(a % b); // 1 → 取余(10÷3=3 余 1)
// 浮点数除法
double result = (double) a / b; // 3.333... → 强转后得到小数
// 自增自减(重点理解)
int x = 5;
int y = x++; // y=5(先赋值,后自增),x=6
int z = ++x; // z=7(先自增,后赋值),x=7
int score = 85; // 比较运算
boolean pass = score >= 60; // true → 大于等于
boolean excellent = score >= 90; // false → 大于等于
boolean same = (score == 85); // true → 等于
boolean different = (score != 0); // true → 不等于
// 实际应用
if (score > 90) {
System.out.println("优秀");
} else if (score >= 60) {
System.out.println("及格"); // 输出这个
} else {
System.out.println("不及格");
}
int age = 18;
boolean hasID = true;
boolean hasMoney = false;
// 逻辑与:必须都满足
if (age >= 18 && hasID) {
System.out.println("可以进入网吧"); // 输出
}
// 逻辑或:满足一个即可
if (hasID || hasMoney) {
System.out.println("可以买烟"); // 输出
}
// 逻辑非:取反
if (!hasMoney) {
System.out.println("没钱了"); // 输出
}
// 短路特性(重要!)
int count = 0;
if (count > 0 && ++count > 0) { // ++count 不会执行
// 因为 count>0 为 false,后面的不再计算
}
System.out.println(count); // 0,不是 1
&&:'都要真,才真' → 一个假,全假(短路:见假就停)||:'一个真,就真' → 全假才假(短路:见真就停)// 格式:条件 ? 值 1 : 值 2
int score = 75;
String result = (score >= 60) ? "及格" : "不及格";
System.out.println(result); // 及格
// 相当于
if (score >= 60) {
result = "及格";
} else {
result = "不及格";
}
// 嵌套使用
int a = 10, b = 20, c = 15;
int max = (a > b) ? (a > c ? a : c) : (b > c ? b : c); // 相当于找 a,b,c 中的最大值
// 单一条件
int age = 16;
if (age >= 18) {
System.out.println("成年");
} else {
System.out.println("未成年"); // 输出
}
// 多重条件(成绩等级)
int score = 85;
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) { // 80-89
System.out.println("B"); // 输出
} else if (score >= 70) {
System.out.println("C");
} else {
System.out.println("D");
}
// 嵌套
int money = 100;
boolean hasCard = true;
if (money > 0) {
if (hasCard) {
System.out.println("可以购物");
} else {
System.out.println("需要现金支付");
}
}
int day = 3;
String dayName;
switch (day) {
case 1: // 如果 day==1
dayName = "星期一";
break; // 必须 break,否则会继续执行下面 case
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三"; // 匹配这个
break;
case 4:
dayName = "星期四";
break;
case 5:
dayName = "星期五";
break;
default: // 都不匹配时执行
dayName = "周末";
break;
}
System.out.println(dayName); // 星期三
// 新的 switch 表达式(JDK14+)
String dayType = switch (day) {
case 1, 2, 3, 4, 5 -> "工作日"; // 1-5 返回"工作日"
case 6, 7 -> "周末"; // 6-7 返回"周末"
default -> "无效"; // 其他返回"无效"
};
for 循环(已知循环次数)
// 打印 1-5
for (int i = 1; i <= 5; i++) {
System.out.println("第" + i + "次循环");
}
// 执行过程:
// i=1 → 打印 → i=2 → 打印 → ... → i=6(不满足条件)→ 结束
// 遍历数组
int[] scores = {90, 85, 78, 92, 88};
for (int i = 0; i < scores.length; i++) {
System.out.println("第" + (i + 1) + "个成绩:" + scores[i]);
}
while 循环(条件控制)
import java.util.Scanner;
// 猜数字游戏
int target = 50;
int guess = 0;
Scanner scanner = new Scanner(System.in);
while (guess != target) { // 条件为 true 就继续循环
System.out.print("猜数字:");
guess = scanner.nextInt();
if (guess > target) {
System.out.println("太大了!");
} else if (guess < target) {
System.out.println("太小了!");
}
}
System.out.println("恭喜猜对!");
do-while 循环(至少执行一次)
import java.util.Scanner;
// 密码验证(至少输入一次)
String password;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("请输入密码:");
password = scanner.nextLine();
} while (!password.equals("123456")); // 先执行,后判断
System.out.println("密码正确!");
// break:立即结束整个循环
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // 当 i=5 时,跳出整个循环
}
System.out.println(i); // 只输出 1,2,3,4
}
// continue:跳过本次循环,继续下一次
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // 跳过 i=3 的情况
}
System.out.println(i); // 输出 1,2,4,5
}
// 标签:控制多层循环 outer
// 给外层循环贴标签
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {
break outer; // 直接跳出外层循环
}
System.out.println(i + "," + j);
}
}
// 输出:1,1 1,2 1,3 2,1(结束)
// 1. 声明数组(三种方式)
int[] arr1; // 方式 1:推荐
int arr2[]; // 方式 2:不推荐
int[] arr3 = new int[5]; // 方式 3:直接初始化长度
// 2. 静态初始化(创建时指定值)
int[] scores = {90, 85, 78, 92, 88};
String[] names = {"张三", "李四", "王五"};
// 3. 动态初始化(先定长度,后赋值)
int[] numbers = new int[3]; // 创建长度为 3 的数组,默认值 [0,0,0]
numbers[0] = 10; // 第一个元素
numbers[1] = 20; // 第二个元素
numbers[2] = 30; // 第三个元素
// numbers[3] = 40; // 错误!数组越界
// 4. 数组特点
System.out.println("数组长度:" + numbers.length); // 3
System.out.println("第一个元素:" + numbers[0]); // 10
System.out.println("最后一个元素:" + numbers[numbers.length - 1]); // 30
// 栈内存存引用,堆内存存数据
int[] arr1 = {10, 20, 30}; // 堆中创建数组对象
int[] arr2 = arr1; // arr2 指向同一个对象
arr2[0] = 100; // 修改 arr2 会影响 arr1
System.out.println(arr1[0]); // 100,不是 10!
// 图解:
// 栈内存 堆内存
// arr1 -----→ [10,20,30](修改前)
// arr2 ----/ ↓ 修改
// [100,20,30](修改后)
int[] numbers = {10, 20, 30, 40, 50};
// 方式 1:普通 for(知道索引时用)
for (int i = 0; i < numbers.length; i++) {
System.out.println("索引" + i + ":" + numbers[i]);
}
// 方式 2:增强 for(只读遍历时用)
for (int num : numbers) {
System.out.println("元素:" + num);
}
// 方式 3:while 循环
int i = 0;
while (i < numbers.length) {
System.out.println(numbers[i]);
i++;
}
// 方式 4:Arrays.toString(快速打印)
System.out.println(Arrays.toString(numbers)); // [10, 20, 30, 40, 50]
// 1. 求最大值
public static int getMax(int[] arr) {
int max = arr[0]; // 假设第一个最大
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i]; // 发现更大的就更新
}
}
return max;
}
// 2. 数组反转
public static void reverse(int[] arr) {
// 首尾交换
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 3. 查找元素
public static int findIndex(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
return i; // 找到返回索引
}
}
return -1; // 没找到返回 -1
}
// 4. 数组求和
public static int sumArray(int[] arr) {
int sum = 0;
for (int num : arr) {
sum += num;
}
return sum;
}
// 1. 声明二维数组(矩阵)
int[][] matrix = {{1, 2, 3}, // 第一行
{4, 5, 6}, // 第二行
{7, 8, 9}}; // 第三行
// 2. 访问元素
System.out.println(matrix[0][0]); // 1(第一行第一列)
System.out.println(matrix[1][2]); // 6(第二行第三列)
// 3. 遍历二维数组(嵌套循环)
for (int i = 0; i < matrix.length; i++) { // 行循环
for (int j = 0; j < matrix[i].length; j++) { // 列循环
System.out.print(matrix[i][j] + "\t");
}
System.out.println(); // 换行
}
// 输出:
// 1 2 3
// 4 5 6
// 7 8 9
// 定义方法:实现特定功能
public class Calculator {
// 加法方法
public static int add(int a, int b) {
int sum = a + b;
return sum; // 返回结果
}
// 判断奇偶方法
public static void checkEvenOdd(int num) {
if (num % 2 == 0) {
System.out.println(num + "是偶数");
} else {
System.out.println(num + "是奇数");
}
// 无返回值,用 void
}
// 求最大值方法
public static int max(int a, int b, int c) {
int max = a;
if (b > max) max = b;
if (c > max) max = c;
return max;
}
}
// 调用方法
public class Main {
public static void main(String[] args) {
// 1. 调用有返回值的方法
int result = Calculator.add(10, 20);
System.out.println("和:" + result); // 30
// 2. 直接输出返回值
System.out.println("最大数:" + Calculator.max(5, 8, 3)); // 8
// 3. 调用无返回值方法
Calculator.checkEvenOdd(7); // 7 是奇数
}
}
// 同一个类中,方法名相同,参数不同
class MathUtils {
// 重载 1:两个 int 相加
public int add(int a, int b) {
return a + b;
}
// 重载 2:三个 int 相加
public int add(int a, int b, int c) {
return a + b + c;
}
// 重载 3:两个 double 相加
public double add(double a, double b) {
return a + b;
}
// 重载 4:两个字符串拼接
public String add(String a, String b) {
return a + b;
}
}
// 编译器根据参数自动选择
MathUtils utils = new MathUtils();
utils.add(1, 2); // 调用第一个
utils.add(1, 2, 3); // 调用第二个
utils.add(1.5, 2.5); // 调用第三个
utils.add("Hello", "World"); // 调用第四个
// 1. 基本类型:传值(拷贝一份)
public static void changeValue(int num) {
num = 100; // 修改的是副本,不影响原值
System.out.println("方法内:" + num); // 100
}
int x = 10;
changeValue(x);
System.out.println("方法外:" + x); // 10(不变!)
// 2. 引用类型:传引用(共享对象)
public static void changeArray(int[] arr) {
arr[0] = 100; // 修改的是堆中的对象
System.out.println("方法内:" + arr[0]); // 100
}
int[] nums = {1, 2, 3};
changeArray(nums);
System.out.println("方法外:" + nums[0]); // 100(变了!)
// 内存图解:
// 基本类型:栈中 x=10 → 拷贝一份 num=10 → num 改为 100,x 还是 10
// 引用类型:栈中 nums 引用 → 堆中 [1,2,3] → 方法内修改为 [100,2,3]
// 1. 返回数据
public static int getAge() {
return 25; // 返回 int 值
}
// 2. 提前结束方法
public static void login(String username, String password) {
if (username == null || password == null) {
System.out.println("用户名或密码不能为空");
return; // 提前结束,不执行后面的代码
}
if (!username.equals("admin")) {
System.out.println("用户名错误");
return; // 提前结束
}
System.out.println("登录成功");
}
// 3. 与 break 的区别
public void test() {
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // 跳出循环,但方法继续执行
// return; // 直接结束整个方法
}
System.out.println(i);
}
System.out.println("循环结束"); // break 会执行这里,return 不会
}
// 1. 定义类(设计图)
public class Student {
// 属性(特征)
String name; // 姓名
int age; // 年龄
double score; // 成绩
// 方法(行为)
public void study() {
System.out.println(name + "正在学习...");
}
public void showInfo() {
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("成绩:" + score);
}
}
// 2. 创建对象(根据设计图制造)
public class Main {
public static void main(String[] args) {
// 创建第一个学生
Student stu1 = new Student();
stu1.name = "张三";
stu1.age = 18;
stu1.score = 90.5;
stu1.study(); // 张三正在学习...
stu1.showInfo();
// 创建第二个学生
Student stu2 = new Student();
stu2.name = "李四";
stu2.age = 19;
stu2.score = 88.0;
stu2.study(); // 李四正在学习...
stu2.showInfo();
// 每个对象独立存在,互不影响
System.out.println(stu1 == stu2); // false(内存地址不同)
}
}
public class Person {
String name;
int age;
// 无参构造器(默认)
public Person() {
System.out.println("一个人出生了");
}
// 有参构造器(常用)
public Person(String name, int age) {
this.name = name; // this 指当前对象
this.age = age;
System.out.println(name + "出生了,年龄" + age);
}
// 构造器重载
public Person(String name) {
this(name, 0); // 调用另一个构造器
}
}
// 使用构造器创建对象
Person p1 = new Person(); // 调用无参构造
Person p2 = new Person("张三", 20); // 调用有参构造
Person p3 = new Person("李四"); // 调用一个参数的构造
public class BankAccount {
// 1. 私有化属性(封装数据)
private String accountNumber; // 账号(别人不能直接看)
private double balance; // 余额(别人不能直接改)
// 2. 提供公共访问方法(控制访问)
public String getAccountNumber() {
// 返回掩码账号:****1234
return "****" + accountNumber.substring(accountNumber.length() - 4);
}
public double getBalance() {
return balance; // 可以查看余额
}
// 3. 提供修改方法(控制修改)
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.println("存款成功,当前余额:" + balance);
} else {
System.out.println("存款金额必须大于 0");
}
}
public boolean withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
System.out.println("取款成功,剩余余额:" + balance);
return true;
} else {
System.out.println("余额不足或金额无效");
return false;
}
}
}
// 使用:外部只能通过规定的方式访问
BankAccount account = new BankAccount();
// account.balance = 1000; // 错误!private 不能直接访问
account.deposit(1000); // 正确!通过方法存钱
account.withdraw(500); // 正确!通过方法取钱
System.out.println(account.getBalance()); // 正确!通过方法查看
// 父类:通用属性和和方法
class Animal {
String name;
int age;
public void eat() {
System.out.println(name + "在吃东西");
}
public void sleep() {
System.out.println(name + "在睡觉");
}
}
// 子类 1:继承父类,添加特有功能
class Dog extends Animal {
// 继承了 name、age 属性和 eat()、sleep() 方法
public void bark() {
System.out.println(name + "汪汪叫"); // 可以直接用父类的 name
}
}
// 子类 2:继承父类,重写方法
class Cat extends Animal {
@Override // 重写父类方法
public void eat() {
System.out.println(name + "在吃鱼"); // 猫吃鱼
}
public void climb() {
System.out.println(name + "在爬树"); // 猫的特有方法
}
}
// 使用继承
Dog dog = new Dog();
dog.name = "旺财"; // 继承的属性
dog.eat(); // 继承的方法
dog.bark(); // 自己的方法
Cat cat = new Cat();
cat.name = "咪咪";
cat.eat(); // 重写的方法:咪咪在吃鱼
cat.climb(); // 自己的方法
// 对象多态:同一个对象,多种形态
Animal a1 = new Dog(); // 狗是动物的一种形态
Animal a2 = new Cat(); // 猫是动物的一种形态
// 行为多态:同一个方法,不同表现
a1.makeSound(); // 汪汪汪
a2.makeSound(); // 喵喵喵
// 1. 继承关系
class Animal {
public void makeSound() {
System.out.println("动物叫");
}
}
// 2. 方法重写
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
}
// 3. 父类引用指向子类对象
Animal animal = new Dog(); // 这就是多态!
animal.makeSound(); // 汪汪汪(实际调用 Dog 的方法)
// 宠物医院:可以治疗所有动物,无需关心具体种类
class PetHospital {
// 参数用 Animal 类型,可以接收所有子类
public void treat(Animal animal) {
animal.makeSound();
System.out.println("正在治疗...");
}
}
// 使用
PetHospital hospital = new PetHospital();
hospital.treat(new Dog()); // 治疗狗
hospital.treat(new Cat()); // 治疗猫
hospital.treat(new Bird()); // 治疗鸟(未来扩展)
// 如果不使用多态,需要写很多重载方法:
// treat(Dog dog), treat(Cat cat), treat(Bird bird)...
Animal animal = new Dog();
// 问题:不能调用子类特有方法
// animal.bark(); // 编译错误!Animal 类型没有 bark 方法
// 解决:类型转换
if (animal instanceof Dog) {
// 1. 先检查类型
Dog dog = (Dog) animal;
// 2. 安全转换
dog.bark();
// 3. 调用特有方法
}
// 自动类型转换(向上转型):安全
Dog myDog = new Dog();
Animal animal2 = myDog; // 自动转,子类→父类
// 强制类型转换(向下转型):不安全
Animal animal3 = new Cat();
// Dog dog2 = (Dog) animal3; // 运行时错误!猫不能转成狗
// 1. final 修饰类:不能被继承
final class MathUtils {
// public static int add(int a, int b){return a + b;}
}
// class AdvancedMath extends MathUtils { } // 错误!
// 2. final 修饰方法:不能被重写
class Vehicle {
public final void startEngine() {
// 关键方法不可修改
System.out.println("启动发动机");
}
}
class Car extends Vehicle {
// public void startEngine() { } // 错误!不能重写 final 方法
}
// 3. final 修饰变量:只能赋值一次
class Student {
final int MAX_AGE = 25; // 基本类型:值不能改
final List<String> courses = new ArrayList<>(); // 引用类型:引用不能改
public Student() {
// MAX_AGE = 30; // 错误!final 变量不能重新赋值
courses.add("数学"); // 正确!可以修改对象内容
courses.add("语文");
// courses = new ArrayList<>(); // 错误!引用不能改变
}
}
// 4. 常量(static final):全局配置
class Constants {
public static final String SCHOOL_NAME = "示例公司";
public static final int MAX_STUDENTS = 50;
}
// 使用常量
System.out.println(Constants.SCHOOL_NAME); // 示例公司
// Constants.SCHOOL_NAME = "其他学校"; // 错误!常量不能改
// 定义抽象类:包含抽象方法的类
abstract class Animal {
String name;
// 抽象方法:只有声明,没有实现
public abstract void makeSound();
// 具体方法:可以有实现
public void eat() {
System.out.println(name + "在吃东西");
}
// 构造器:可以有
public Animal(String name) {
this.name = name;
}
}
// 子类必须实现所有抽象方法
class Dog extends Animal {
public Dog(String name) {
super(name); // 调用父类构造器
}
@Override
public void makeSound() {
System.out.println(name + "汪汪叫");
}
}
class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println(name + "喵喵叫");
}
}
// 使用
Animal dog = new Dog("旺财");
dog.makeSound(); // 旺财汪汪叫
dog.eat(); // 旺财在吃东西(继承的)
// 不能创建抽象类对象
// Animal animal = new Animal(); // 错误!抽象类不能实例化
// 解决代码重复问题
abstract class ReportGenerator {
// 模板方法(final 防止子类修改流程)
public final void generateReport() {
loadData(); // 1. 加载数据(抽象)
processData(); // 2. 处理数据(抽象)
saveReport(); // 3. 保存报告(具体)
sendEmail(); // 4. 发送邮件(可选)
}
// 抽象方法:子类必须实现
protected abstract void loadData();
protected abstract void processData();
// 具体方法:通用实现
protected void saveReport() {
System.out.println("保存报告到文件");
}
// 钩子方法:子类可选重写
protected void sendEmail() {
System.out.println("发送邮件通知");
}
}
// 具体实现类
class ExcelReport extends ReportGenerator {
@Override
protected void loadData() {
System.out.println("从 Excel 加载数据");
}
@Override
protected void processData() {
System.out.println("处理 Excel 数据");
}
@Override
protected void saveReport() {
System.out.println("保存为 Excel 文件");
}
}
class DatabaseReport extends ReportGenerator {
@Override
protected void loadData() {
System.out.println("从数据库加载数据");
}
@Override
protected void processData() {
System.out.println("处理数据库数据");
}
// 不重写 sendEmail,使用默认实现
}
// 使用
ReportGenerator excel = new ExcelReport();
excel.generateReport(); // 按模板流程执行
import java.util.List;
import java.util.ArrayList;
// 定义接口(能力约定)
interface Flyable {
// 常量(默认 public static final)
double MAX_HEIGHT = 10000.0;
// 抽象方法(默认 public abstract)
void fly();
// 默认方法(JDK8+)
default void glide() {
System.out.println("滑翔中...");
}
// 静态方法(JDK8+)
static void showInfo() {
System.out.println("飞行器最高高度:" + MAX_HEIGHT);
}
}
// 实现接口(获得能力)
class Bird implements Flyable {
String name;
@Override
public void fly() {
System.out.println(name + "在飞翔");
}
@Override
public void glide() {
System.out.println(name + "优雅地滑翔");
}
}
class Airplane implements Flyable {
@Override
public void fly() {
System.out.println("飞机在飞行");
}
}
// 使用
Flyable bird = new Bird();
bird.fly(); // 调用实现的方法
bird.glide(); // 调用默认方法
Flyable.showInfo(); // 调用静态方法
// 定义支付接口
interface Payment {
boolean pay(double amount);
boolean refund(double amount);
}
// 不同实现
class Alipay implements Payment {
@Override
public boolean pay(double amount) {
System.out.println("支付宝支付:" + amount);
return true;
}
@Override
public boolean refund(double amount) {
System.out.println("支付宝退款:" + amount);
return true;
}
}
class WechatPay implements Payment {
@Override
public boolean pay(double amount) {
System.out.println("微信支付:" + amount);
return true;
}
@Override
public boolean refund(double amount) {
System.out.println("微信退款:" + amount);
return true;
}
}
// 业务类依赖接口,不依赖具体实现
class OrderService {
private Payment payment; // 通过构造器注入支付方式
public OrderService(Payment payment) {
this.payment = payment;
}
public void processOrder(double amount) {
if (payment.pay(amount)) {
System.out.println("订单支付成功");
}
}
}
// 使用:灵活切换支付方式
OrderService alipayOrder = new OrderService(new Alipay());
alipayOrder.processOrder(100.0);
OrderService wechatOrder = new OrderService(new WechatPay());
wechatOrder.processOrder(200.0);
// 接口可以多继承
interface Swimmable {
void swim();
}
interface Flyable {
void fly();
}
// 多继承接口
interface Amphibious extends Swimmable, Flyable {
void transform();
}
// 类可以实现多个接口
class Duck implements Swimmable, Flyable {
@Override
public void swim() {
System.out.println("鸭子在游泳");
}
@Override
public void fly() {
System.out.println("鸭子在飞");
}
}
class Robot implements Amphibious {
@Override
public void swim() {
System.out.println("机器人在水中");
}
@Override
public void fly() {
System.out.println("机器人在空中");
}
@Override
public void transform() {
System.out.println("机器人变形");
}
}
// 场景:员工管理系统
// 接口:定义能力
interface Workable {
void work();
}
interface Eatable {
void eat();
}
// 抽象类:共享代码
abstract class Employee {
String name;
int id;
public Employee(String name, int id) {
this.name = name;
this.id = id;
}
public abstract double calculateSalary();
public void showInfo() {
System.out.println("员工:" + name + ",ID:" + id);
}
}
// 具体类:继承抽象类 + 实现接口
class Programmer extends Employee implements Workable {
double salary;
public Programmer(String name, int id, double salary) {
super(name, id);
this.salary = salary;
}
@Override
public double calculateSalary() {
return salary;
}
@Override
public void work() {
System.out.println(name + "在写代码");
}
}
class Chef extends Employee implements Workable, Eatable {
double hourlyRate;
int hours;
public Chef(String name, int id, double hourlyRate, int hours) {
super(name, id);
this.hourlyRate = hourlyRate;
this.hours = hours;
}
@Override
public double calculateSalary() {
return hourlyRate * hours;
}
@Override
public void work() {
System.out.println(name + "在做饭");
}
@Override
public void eat() {
System.out.println(name + "在品尝菜品");
}
}
// 1. 创建字符串
String s1 = "Hello"; // 字面量(推荐)
String s2 = new String("Hello"); // new 对象
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String s3 = new String(chars); // 字符数组
// 2. 常用方法
String str = "Hello World Java";
// 获取信息
int len = str.length(); // 长度:15
char ch = str.charAt(1); // 索引 1 的字符:'e'
// 查找
int idx1 = str.indexOf("World"); // 第一次出现位置:6
int idx2 = str.lastIndexOf("l"); // 最后一次出现:9
boolean has = str.contains("Java"); // 是否包含:true
// 截取
String sub1 = str.substring(6); // "World Java"(从 6 开始)
String sub2 = str.substring(6, 11); // "World"([6,11))
// 分割
String[] words = str.split(" "); // ["Hello","World","Java"]
// 替换
String newStr1 = str.replace("Java", "Python"); // "Hello World Python"
String newStr2 = str.replaceAll("\\s", "-"); // "Hello-World-Java"
// 大小写
String upper = str.toUpperCase(); // "HELLO WORLD JAVA"
String lower = str.toLowerCase(); // "hello world java"
// 去除空格
String trim = " Hello ".trim(); // "Hello"
// 3. 字符串比较(重要!)
String a = "hello";
String b = new String("hello");
System.out.println(a == b); // false(比较地址)
System.out.println(a.equals(b)); // true(比较内容)
System.out.println(a.equalsIgnoreCase("HELLO")); // true(忽略大小写)
// 4. 字符串构建(性能优化)
// 错误:每次拼接都创建新对象
String result = "";
for (int i = 0; i < 10000; i++) {
result += i; // 效率极低!
}
// 正确:使用 StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
sb.append(i); // 高效
}
String finalResult = sb.toString();
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
// 1. 创建 ArrayList
List<String> list = new ArrayList<>(); // 推荐写法
ArrayList<String> list2 = new ArrayList<>(); // 也可以
// 2. 添加元素
list.add("苹果");
list.add("香蕉");
list.add("橙子");
list.add(1, "葡萄"); // 在索引 1 处插入
// 3. 获取元素
String fruit = list.get(0); // "苹果"
int size = list.size(); // 4
// 4. 修改元素
list.set(2, "西瓜"); // 将索引 2 改为"西瓜"
// 5. 删除元素
list.remove(0); // 删除索引 0
list.remove("香蕉"); // 删除指定元素
// 6. 遍历
// 方式 1:普通 for(需要索引时用)
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 方式 2:增强 for(推荐)
for (String item : list) {
System.out.println(item);
}
// 方式 3:迭代器(删除元素时安全)
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (item.equals("葡萄")) {
iterator.remove(); // 安全删除
}
}
// 方式 4:Java8 forEach
list.forEach(item -> System.out.println(item));
list.forEach(System.out::println); // 方法引用
// 7. 其他方法
boolean empty = list.isEmpty(); // 是否为空
boolean has = list.contains("苹果"); // 是否包含
int idx = list.indexOf("橙子"); // 查找索引
list.clear(); // 清空所有
import java.time.*;
import java.time.format.*;
// 1. 获取当前时间
LocalDate today = LocalDate.now(); // 日期:2025-01-18
LocalTime now = LocalTime.now(); // 时间:14:30:45.123
LocalDateTime current = LocalDateTime.now(); // 日期时间
// 2. 创建特定时间
LocalDate birthday = LocalDate.of(2000, 1, 1); // 2000-01-01
LocalTime meeting = LocalTime.of(14, 30, 0); // 14:30:00
LocalDateTime event = LocalDateTime.of(2025, 12, 25, 20, 0, 0);
// 3. 操作日期
LocalDate tomorrow = today.plusDays(1); // 加 1 天
LocalDate lastWeek = today.minusWeeks(1); // 减 1 周
LocalDate nextMonth = today.plusMonths(1); // 加 1 月
// 4. 获取信息
int year = today.getYear(); // 年
Month month = today.getMonth(); // 月(枚举)
int day = today.getDayOfMonth(); // 日
DayOfWeek weekday = today.getDayOfWeek(); // 星期
// 5. 格式化
DateTimeFormatter fmt1 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
DateTimeFormatter fmt2 = DateTimeFormatter.ofPattern("yyyy 年 MM 月 dd 日 HH:mm:ss");
String str1 = today.format(fmt1); // "2025-01-18"
String str2 = current.format(fmt2); // "2025 年 01 月 18 日 14:30:45"
// 6. 解析
LocalDate parsed = LocalDate.parse("2025-12-25", fmt1);
// 7. 计算时间差
LocalDate start = LocalDate.of(2025, 1, 1);
LocalDate end = LocalDate.of(2025, 12, 31);
Period period = Period.between(start, end);
System.out.println(period.getDays()); // 相差天数
System.out.println(period.getMonths()); // 相差月数
System.out.println(period.getYears()); // 相差年数
// 1. 运行时异常(RuntimeException)- 可以不处理
// 数组越界
int[] arr = {1, 2, 3};
// System.out.println(arr[5]); // ArrayIndexOutOfBoundsException
// 空指针
String str = null;
// System.out.println(str.length()); // NullPointerException
// 类型转换
Object obj = "hello";
// Integer num = (Integer) obj; // ClassCastException
// 数学异常
// int result = 10 / 0; // ArithmeticException
// 2. 编译时异常(Checked Exception)- 必须处理
// FileNotFoundException, IOException, SQLException 等
// FileReader reader = new FileReader("test.txt"); // 需要处理异常
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
// 基本结构
try {
// 可能抛出异常的代码
int result = 10 / 0;
System.out.println("结果:" + result);
} catch (ArithmeticException e) {
// 捕获算术异常
System.out.println("除数不能为零:" + e.getMessage());
} catch (Exception e) {
// 捕获其他所有异常
System.out.println("发生错误:" + e);
} finally {
// 无论是否异常都会执行(清理资源)
System.out.println("执行 finally 块");
}
// 多重 catch 注意事项
try {
String str = null;
str.length();
int x = 10 / 0;
} catch (NullPointerException e) {
System.out.println("空指针异常");
} catch (ArithmeticException e) {
System.out.println("算术异常");
} catch (Exception e) {
System.out.println("其他异常");
}
// 只会捕获第一个发生的异常(NullPointerException)
// try-with-resources(自动关闭资源)
try (FileReader reader = new FileReader("test.txt"); BufferedReader br = new BufferedReader(reader)) {
// 自动关闭 reader 和 br
String line = br.readLine();
System.out.println(line);
} catch (IOException e) {
e.printStackTrace();
}
// throw:手动抛出异常
public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("取款金额必须大于 0");
}
if (amount > balance) {
throw new RuntimeException("余额不足");
}
balance -= amount;
}
// throws:声明方法可能抛出的异常
public void readFile(String filename) throws FileNotFoundException, IOException {
FileReader reader = new FileReader(filename); // 读取文件...
reader.close();
}
// 自定义异常
class InsufficientBalanceException extends Exception {
private double balance;
private double amount;
public InsufficientBalanceException(double balance, double amount) {
super("余额不足:当前余额" + balance + ",需要" + amount);
this.balance = balance;
this.amount = amount;
}
public double getBalance() {
return balance;
}
public double getAmount() {
return amount;
}
}
// 使用自定义异常
public void transfer(double amount) throws InsufficientBalanceException {
if (amount > balance) {
throw new InsufficientBalanceException(balance, amount);
}
balance -= amount;
}
import java.util.List;
import java.util.ArrayList;
// 1. 泛型类
class Box<T> {
private T content;
public void setContent(T content) {
this.content = content;
}
public T getContent() {
return content;
}
}
// 使用泛型类
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String str = stringBox.getContent(); // 不需要强制转换
Box<Integer> intBox = new Box<>();
intBox.setContent(100);
int num = intBox.getContent(); // 自动拆箱
// 2. 泛型方法
class ArrayUtils {
// 泛型方法声明:<T>在返回值前
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
// 多个类型参数
public static <K, V> void printPair(K key, V value) {
System.out.println(key + " -> " + value);
}
}
// 使用泛型方法
String[] names = {"张三", "李四", "王五"};
ArrayUtils.printArray(names); // 张三 李四 王五
Integer[] numbers = {1, 2, 3, 4, 5};
ArrayUtils.printArray(numbers); // 1 2 3 4 5
ArrayUtils.printPair("姓名", "张三"); // 姓名 -> 张三
// 3. 泛型通配符
class WildcardExample {
// 无界通配符:可以接收任何类型
public void printList(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}
// 上界通配符:只能是 Number 或其子类
public double sum(List<? extends Number> list) {
double total = 0;
for (Number num : list) {
total += num.doubleValue();
}
return total;
}
// 下界通配符:只能是 Integer 或其父类
public void addNumbers(List<? super Integer> list) {
for (int i = 1; i <= 5; i++) {
list.add(i);
}
}
}
import java.util.EnumSet;
import java.util.EnumMap;
import java.sql.Connection;
// 1. 基本枚举
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
// 2. 带属性和方法的枚举
enum Color {
RED("#FF0000", "红色"), GREEN("#00FF00", "绿色"), BLUE("#0000FF", "蓝色");
private final String hexCode;
private final String chinese;
Color(String hexCode, String chinese) {
this.hexCode = hexCode;
this.chinese = chinese;
}
public String getHexCode() {
return hexCode;
}
public String getChinese() {
return chinese;
}
public void printInfo() {
System.out.println(chinese + "的十六进制是:" + hexCode);
}
}
// 3. 实现接口的枚举
interface Operation {
double apply(double x, double y);
}
enum Calculator implements Operation {
ADD {
@Override
public double apply(double x, double y) {
return x + y;
}
}, SUBTRACT {
@Override
public double apply(double x, double y) {
return x - y;
}
}, MULTIPLY {
@Override
public double apply(double x, double y) {
return x * y;
}
}, DIVIDE {
@Override
public double apply(double x, double y) {
return x / y;
}
};
}
// 使用枚举
Day today = Day.MONDAY;
System.out.println(today); // MONDAY
System.out.println(today.ordinal()); // 0(序号)
Color red = Color.RED;
System.out.println(red.getChinese()); // 红色
red.printInfo(); // 红色的十六进制是:#FF0000
double result = Calculator.ADD.apply(10, 5); // 15.0
// 4. 枚举集合
EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
EnumMap<Day, String> schedule = new EnumMap<>(Day.class);
schedule.put(Day.MONDAY, "会议");
schedule.put(Day.TUESDAY, "编码");
// 5. 枚举单例模式
enum DatabaseConnection {
INSTANCE;
private Connection connection;
private DatabaseConnection() {
// 初始化连接
}
public Connection getConnection() {
return connection;
}
}
// 使用:DatabaseConnection.INSTANCE.getConnection()
| 场景 | 推荐类型 | 示例 |
|---|---|---|
| 年龄、数量 | int | int age = 25; |
| 金额、分数 | double | double price = 19.99; |
| 真假判断 | boolean | boolean isPass = true; |
| 单个字符 | char | char grade = 'A'; |
| 大整数 | long | long population = 1400000000L; |
| 小数值 | float | float pi = 3.14f; |
| 字节数据 | byte | byte[] fileData = ...; |
| 需求 | 推荐循环 | 示例 |
|---|---|---|
| 已知循环次数 | for | for (int i=0; i<10; i++) |
| 遍历集合数组 | 增强 for | for (String s : list) |
| 条件控制循环 | while | while (x < 100) |
| 至少执行一次 | do-while | do {...} while (条件) |
| 需要索引操作 | 普通 for | for (int i=0; i<arr.length; i++) |
| 需求 | 推荐集合 | 特点 |
|---|---|---|
| 快速随机访问 | ArrayList | 基于数组,查询 O(1) |
| 频繁插入删除 | LinkedList | 基于链表,插入删除 O(1) |
| 元素去重 | HashSet | 哈希表,无序 |
| 去重并有序 | LinkedHashSet | 保持插入顺序 |
| 自动排序 | TreeSet | 红黑树,自然排序 |
| 键值对存储 | HashMap | 哈希表,无序 |
| 键值对有序 | LinkedHashMap | 保持插入顺序 |
| 键值对排序 | TreeMap | 按键排序 |
| 原则 | 说明 | 示例 |
|---|---|---|
| 单一职责 | 一个类只做一件事 | 用户管理类只管用户,不分发邮件 |
| 开闭原则 | 对扩展开放,对修改关闭 | 用接口/抽象类,新增功能加类不改旧代码 |
| 里氏替换 | 子类可以替换父类 | Animal animal = new Dog(); 能正常工作 |
| 接口隔离 | 接口要小而专 | 拆分大接口为多个小接口 |
| 依赖倒置 | 依赖抽象不依赖具体 | 用 List 接口,不用 ArrayList 具体类 |
| 错误信息 | 可能原因 | 解决方案 |
|---|---|---|
| NullPointerException | 对象为 null | 检查对象初始化 |
| ArrayIndexOutOfBounds | 数组越界 | 检查索引范围 0~(length-1) |
| ClassCastException | 类型转换错误 | 先 instanceof 检查再转换 |
| ArithmeticException | 除数为零 | 检查除数是否为 0 |
| NumberFormatException | 数字格式错误 | 检查字符串是否能转为数字 |
| FileNotFoundException | 文件不存在 | 检查文件路径和权限 |
import java.util.logging.Logger;
// 1. 打印调试法
System.out.println("变量值:" + variable);
System.out.println("进入方法:" + methodName);
// 2. 断言调试法
assert value != null : "值不能为空";
assert index >= 0 && index < array.length : "索引越界";
// 3. 日志调试法
Logger logger = Logger.getLogger("MyApp");
logger.info("开始处理...");
logger.warning("可能有问题...");
logger.severe("严重错误!");
// 4. IDE 调试技巧
// - F8:单步执行(不进入方法)
// - F7:单步执行(进入方法)
// - F9:继续执行到下一个断点
// - Alt+F8:计算表达式
// - Ctrl+F8:切换断点
// - 条件断点:右键断点设置条件
import java.util.List;
import java.util.ArrayList;
// 实体类
class Student {
private int id;
private String name;
private int age;
private double score;
public Student(int id, String name, int age, double score) {
this.id = id;
this.name = name;
this.age = age;
this.score = score;
}
// getter/setter...
@Override
public String toString() {
return String.format("学号:%d,姓名:%s,年龄:%d,成绩:%.1f", id, name, age, score);
}
}
// 业务类
class StudentManager {
private List<Student> students = new ArrayList<>();
// 添加学生
public void addStudent(Student stu) {
students.add(stu);
System.out.println("添加成功:" + stu.getName());
}
// 删除学生
public boolean removeStudent(int id) {
for (int i = 0; i < students.size(); i++) {
if (students.get(i).getId() == id) {
Student removed = students.remove(i);
System.out.println("删除成功:" + removed.getName());
return true;
}
}
System.out.println("未找到学号为" + id + "的学生");
return false;
}
// 查找学生
public Student findStudent(int id) {
for (Student stu : students) {
if (stu.getId() == id) {
return stu;
}
}
return null;
}
// 显示所有学生
public void showAllStudents() {
if (students.isEmpty()) {
System.out.println("暂无学生信息");
return;
}
System.out.println("====== 学生列表 ======");
for (Student stu : students) {
System.out.println(stu);
}
System.out.println("=====================");
}
// 按成绩排序
public void sortByScore() {
students.sort((s1, s2) -> Double.compare(s2.getScore(), s1.getScore()));
System.out.println("按成绩排序完成");
}
// 统计平均分
public double getAverageScore() {
if (students.isEmpty()) return 0;
double total = 0;
for (Student stu : students) {
total += stu.getScore();
}
return total / students.size();
}
}
// 测试类
public class TestStudentManager {
public static void main(String[] args) {
StudentManager manager = new StudentManager();
// 添加学生
manager.addStudent(new Student(1001, "张三", 18, 90.5));
manager.addStudent(new Student(1002, "李四", 19, 88.0));
manager.addStudent(new Student(1003, "王五", 20, 92.5));
// 显示所有
manager.showAllStudents();
// 查找学生
Student stu = manager.findStudent(1002);
if (stu != null) {
System.out.println("找到学生:" + stu);
}
// 排序
manager.sortByScore();
manager.showAllStudents();
// 统计
System.out.printf("平均分:%.2f\n", manager.getAverageScore());
}
}

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online