文章目录
- 一、编程基础
-
- [(一) this关键字](#(一) this关键字)
-
- [1. 访问当前对象的属性、方法](#1. 访问当前对象的属性、方法)
- [2. 解决变量名冲突](#2. 解决变量名冲突)
- [(二) 成员变量与局部变量的区别](#(二) 成员变量与局部变量的区别)
- [(三) 包与API](#(三) 包与API)
- [(四) String类(字符串处理)](#(四) String类(字符串处理))
- [(五) ArrayList集合(可变数据容器)](#(五) ArrayList集合(可变数据容器))
- [(六) static关键字(静态修饰符)](#(六) static关键字(静态修饰符))
- [(七) 单例设计模式](#(七) 单例设计模式)
- 二、面向对象三大特性
-
- [(一) 封装与实体类(JavaBean)](#(一) 封装与实体类(JavaBean))
- [(二) 继承(extends)](#(二) 继承(extends))
- [(三) 多态(面向对象三大特征之三)](#(三) 多态(面向对象三大特征之三))
- 三、基础工具类
-
- [(一) final关键字(最终修饰符)](#(一) final关键字(最终修饰符))
- [(二) 抽象类(abstract)](#(二) 抽象类(abstract))
- [(三) 接口(interface)](#(三) 接口(interface))
- [(四) 内部类(类中类,封装子事物)](#(四) 内部类(类中类,封装子事物))
- [(五) 枚举(特殊类)](#(五) 枚举(特殊类))
- [(六) 泛型(参数化类型)](#(六) 泛型(参数化类型))
-
- [1. 三种形式](#1. 三种形式)
- [2. 泛型通配符与上下限](#2. 泛型通配符与上下限)
- [(七) 常用API(java.lang包核心)](#(七) 常用API(java.lang包核心))
-
- [1. Object类(所有类的祖宗类)](#1. Object类(所有类的祖宗类))
- [2. 克隆的两种方式](#2. 克隆的两种方式)
- [3. Objects工具类](#3. Objects工具类)
- [4. 包装类(基本类型→对象)](#4. 包装类(基本类型→对象))
- [5. StringBuilder(可变字符串)](#5. StringBuilder(可变字符串))
- [6. StringJoiner(JDK8+,简化拼接)](#6. StringJoiner(JDK8+,简化拼接))
- [(八) 基础工具类](#(八) 基础工具类)
-
- [1. Math(数学工具类)](#1. Math(数学工具类))
- [2. System(系统工具类)](#2. System(系统工具类))
- [3. Runtime(运行环境类)](#3. Runtime(运行环境类))
- [(九) BigDecimal(高精度小数)](#(九) BigDecimal(高精度小数))
- [(十) 日期与时间API(JDK8+)](#(十) 日期与时间API(JDK8+))
- [(十一) Arrays(数组工具类)](#(十一) Arrays(数组工具类))
- [(十二) Lambda表达式(简化匿名内部类)](#(十二) Lambda表达式(简化匿名内部类))
- [(十三) 异常(程序错误处理)](#(十三) 异常(程序错误处理))
- [(十四) File类(文件/文件夹操作)](#(十四) File类(文件/文件夹操作))
一、编程基础
(一) this关键字
1. 访问当前对象的属性、方法
执行原理:
- 调用对象方法时,JVM自动将对象地址传递给
this。 - 通过
this可访问当前对象的成员变量和方法。
java
public class Student {
String name;
public void printThis() {
System.out.println(this); // 输出当前对象的地址(如com.itheima.Student@776ec8df)
}
}
// 测试
Student s1 = new Student();
s1.printThis(); // this指向s1
Student s2 = new Student();
s2.printThis(); // this指向s2
2. 解决变量名冲突
当成员变量与局部变量名一致时,用this区分成员变量(否则优先使用局部变量):
java
public class Student {
double score; // 成员变量
// 参数名score与成员变量名冲突
public void checkPass(double score) {
// this.score 指成员变量,score指参数
if (this.score >= score) {
System.out.println("恭喜考上哈佛!");
} else {
System.out.println("未考上");
}
}
}
(二) 成员变量与局部变量的区别
| 区别维度 | 成员变量(类中方法外) | 局部变量(方法内/参数) |
|---|---|---|
| 类中位置 | 类中,方法外部 | 方法内部、方法参数、代码块中 |
| 初始化值 | 有默认值(无需手动初始化) | 无默认值,使用前必须赋值 |
| 内存存储位置 | 堆内存(随对象存储) | 栈内存(随方法调用存储) |
| 作用域 | 整个对象(类内可访问) | 仅在所属代码块(如方法)内有效 |
| 生命周期 | 与对象共存亡(对象销毁则消失) | 随方法调用而生,方法执行结束则消失 |
(三) 包与API
- API定义:即应用程序编程接口,是他人编写的可直接调用的程序,用于快速解决开发问题。
- 包的核心作用 :类似文件夹,用于分门别类管理程序,方便维护。
- 包的使用规则 :
- 同包内程序可直接调用;
- 异包程序需导包(语法import 包名.类名;);
- 调用不同包下同名类时,一个用import导入,另一个需带完整包名访问(如
com.itheima.A a = new com.itheima.A();)
(四) String类(字符串处理)
- 核心作用:创建对象封装字符串数据,并提供方法处理字符串(如截取、比较)。
- 对象创建方式 :
- 双引号定义:
String 变量名 = "字符串内容";存储于字符串常量池(堆内存中),同内容仅存1份; - new + 构造器:
new String(参数)(支持空白、字符串、字符 / 字节数组),每 new 一次在堆内存生成新对象。
- 双引号定义:
- 关键特性:String对象不可变,"修改"实际是生成新对象。
- 比较方式:推荐用 equals() (比内容),==仅比地址(易出bug,仅基本类型用)。
| 构造器 | 说明 |
|---|---|
| public String() | 创建空白字符串(无内容) |
| public String(String original) | 根据传入字符串创建对象 |
| public String(char[] chars) | 根据字符数组创建对象 |
| public String(byte[] bytes) | 根据字节数组创建对象(按ASCII解析) |
| 方法名 | 说明 |
|---|---|
| public int length() | 获取字符串长度(字符个数) |
| public char charAt(int index) | 获取指定索引处的字符(索引从0开始) |
| public char[] toCharArray() | 将字符串转为字符数组返回 |
| public boolean equals (Object obj) | 比较两个字符串内容是否相同(推荐) |
| public boolean equalsIgnoreCase(String s) | 比较内容(忽略大小写) |
| public String substring (int begin, int end) | 截取字符串(包前不包后) |
| public String substring(int begin) | 从begin索引截取到字符串末尾 |
| public String replace (CharSequence old, CharSequence new) | 替换字符串中的旧值为新值 |
| public boolean contains(CharSequence s) | 判断字符串是否包含指定内容 |
| public boolean startsWith(String prefix) | 判断字符串是否以指定内容开头 |
| public String[] split(String regex) | 按指定规则分割字符串,返回字符串数组 |
(五) ArrayList集合(可变数据容器)
ArrayList是最常用的可变数据容器,无参构造创建空集合(new ArrayList<>())
| 方法名 | 说明 |
|---|---|
| public boolean add(E e) | 末尾添加元素,返回是否成功 |
| public void add(int index, E e) | 指定索引插入元素(索引需合法) |
| public E get(int index) | 获取指定索引的元素 |
| public int size() | 返回集合中元素个数(类似数组length) |
| public E remove(int index) | 删除指定索引元素,返回被删元素 |
| public boolean remove(Object o) | 删除指定内容的元素,返回是否成功 |
| public E set(int index, E e) | 修改指定索引元素,返回旧元素 |
遍历删除防bug
- 删除后索引-1
每次删除元素后,将循环索引减1,避免下一次遍历跳过元素:
java
for (int i = 0; i < list.size(); i++) {
if ("黑马".equals(list.get(i))) {
list.remove(i);
i--; // 索引回退,避免漏删
}
}
- 从后向前遍历
从集合末尾开始遍历,删除元素不影响前面元素的索引:
java
for (int i = list.size() - 1; i >= 0; i--) {
if ("黑马".equals(list.get(i))) {
list.remove(i);
}
}
(六) static关键字(静态修饰符)
实现"数据/方法共享",摆脱对象依赖。
- 成员变量分类:
| 类型 | 修饰符 | 归属 | 使用方式 | 特点(核心区别) |
|---|---|---|---|---|
| 类变量 | static | 类 | 类名.类变量(推荐) 对象.类变量(不推荐) | 与类一起加载,内存中仅1份,所有对象共享 |
| 实例变量 | 无 | 对象 | 对象.实例变量 | 每个对象1份,对象间数据独立 |
- 成员方法分类:
| 类型 | 修饰符 | 归属 | 使用方式 | 访问权限(核心规则) |
|---|---|---|---|---|
| 类方法 | static | 类 | 类名.类方法(推荐) | 仅能直接访问类成员(类变量、类方法), 不能访问实例成员、不能用this |
| 实例方法 | 无 | 对象 | 对象.实例方法 | 可直接访问类成员和实例成员,能用this |
- 代码块(static与实例代码块):
| 类型 | 格式 | 执行时机 | 作用 |
|---|---|---|---|
| 静态代码块 | static {} | 类加载时执行(仅1次) | 初始化类变量(如加载配置文件) |
| 实例代码块 | {} | 每次创建对象时执行(在构造器前) | 初始化实例变量(补充构造器功能) |
(七) 单例设计模式
核心目标 :确保类仅能创建1个对象,避免内存浪费(如任务管理器)。
核心实现逻辑:私有构造器(禁外部new)、类变量存唯一实例、类方法返回唯一实例。
两种实现方式:
- 饿汉式:类加载时创实例,线程安全但可能浪费内存;
java
public class Singleton {
// 1. 私有构造器
private Singleton() {}
// 2. 类变量存储唯一实例
private static Singleton instance = new Singleton();
// 3. 类方法返回实例
public static Singleton getInstance() {
return instance;
}
}
- 懒汉式:调用方法时创实例(延迟加载),节省内存但非线程安全。
java
public class Singleton {
private Singleton() {}
private static Singleton instance; // 初始为null
public static Singleton getInstance() {
if (instance == null) { // 为空时才创建
instance = new Singleton();
}
return instance;
}
}
二、面向对象三大特性
(一) 封装与实体类(JavaBean)
封装作用:数据安全与解耦
专用于存储数据的类,需满足:属性私有、方法公开,实现"数据与业务逻辑分离"。
java
public class Student {
// 1. 私有成员变量
private String name;
private double chinese;
// 2. 无参构造器
public Student() {}
// 3. get/set方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name; // 用this解决变量冲突
}
public double getChinese() {
return chinese;
}
public void setChinese(double chinese) {
this.chinese = chinese;
}
}
(二) 继承(extends)
- 核心作用:建立父子类关系,子类复用父类**非私有成员,**减少重复代码。
- 定义语法 :
public class 子类名 extends 父类名 {} - 对象创建:子类对象由"子类+父类"共同初始化(父类成员先初始化,子类后初始化)。
权限修饰符(控制成员访问范围):
| 修饰符 | 本类 | 同包类 | 子类(异包) | 任意类 |
|---|---|---|---|---|
| private | √ | × | × | × |
| 缺省 | √ | √ | × | × |
| protected | √ | √ | √ | × |
| public | √ | √ | √ | √ |
-
方法重写:
子类重写父类方法需满足
"方法名/参数列表一致、权限≥父类、返回值一致或更小",加@Override校验; -
继承限制:Java
单继承(1个直接父类)、支持多层继承,Object是所有类的祖宗类; -
构造器调用:子类构造器必先调用父类构造器(默认super(),父类无无参构造器需手动写super(参数));
| 关键字 | 核心作用 | 访问成员变量 | 访问成员方法 | 访问构造器 |
|---|---|---|---|---|
| this | 本类对象引用 | this.本类变量 | this.本类方法(...) | this(...)(调用本类其他构造器) |
| super | 父类存储空间标识 | super.父类变量(子父类重名时用) | super.父类方法(...) (调用父类方法) | super(...)(调用父类构造器) |
(三) 多态(面向对象三大特征之三)
"对象多态、行为多态"
三个前提:
- 存在继承或实现关系(子类继承父类,或类实现接口);
- 子类(或实现类)重写了父类(或接口)的方法;
- 父类(或接口)引用指向子类(或实现类)对象(如 Parent p = new Child();)。
核心表现是"编译看左,运行看右",
属性不参与多态,无论编译还是运行阶段,通过父类引用访问的属性均为父类中声明的属性
好处与问题:
- 解耦(子类对象灵活切换)、扩展性强(父类形参接收所有子类);
- 但无法直接调用子类独有方法;
解决方案:
| 转换类型 | 语法 | 适用场景 | 特点 |
|---|---|---|---|
| 自动转换 | 父类类型 变量 = 子类对象; | 多态的初始化(父类引用指向子类) | 无需手动操作,安全 |
| 强制转换 | 子类类型 变量 = (子类类型)父类变量; | 调用子类独有方法 | 需手动操作,存在安全风险 |
风险:
- 若父类引用的真实对象类型与强转后的类型不一致,运行时会报ClassCastException(类型转换异常)。
示例:
java
People p = new Teacher();
Student s = (Student)p;
//运行报错,Teacher不能转Student
解决方案:
- 强转前用 instanceof 判断对象真实类型
- 语法:
对象 instanceof 类型(返回boolean)
示例:
java
if (p instanceof Student) {
Student s = (Student)p;
s.test(); // 安全调用子类独有方法
} else if (p instanceof Teacher) {
Teacher t = (Teacher)p;
t.teach();
}
三、基础工具类
(一) final关键字(最终修饰符)
- 常量 :
static final修饰,全大写(多单词下划线连接),编译期"宏替换",用于存储系统配置。
| 修饰对象 | 效果 | 示例 |
|---|---|---|
| 类 | 类成为"最终类",不能被继承 | final class A { } class B extends A { }报错 |
| 方法 | 方法成为"最终方法",不能被重写 | class C { public final void test() {} } // 子类重写test()报错 |
| 变量 | 变量仅能赋值1次(赋值后不可修改) | final int a = 10; a = 20; //报错 |
注意:
基本类型变量 :存储的数据值 不可修改;
引用类型变量 :存储的对象地址不可修改,但对象内部的属性可修改。
示例:
java
final Student s = new Student();
s.setName("张三"); // 允许(修改对象属性)
s = new Student(); // 报错(修改地址)
(二) 抽象类(abstract)
- 抽象类是 abstract 修饰,仅有方法签名,无方法体(需子类实现)
- 用于抽取子类共性、定义规范,支持多态扩展。
- 有抽象方法的类必是抽象类,不能实例化
- 子类需重写所有抽象方法(否则子类也为抽象类);
java
// 抽象类 示例:
public abstract class Animal {
// 抽象方法(无方法体)
public abstract void cry();
// 抽象类可包含普通成员(变量、方法、构造器)
private String name;
public void setName(String name) {
this.name = name;
}
}
模板方法设计模式(抽象类的典型应用)
重复代码抽为模板方法,差异化逻辑抽为抽象方法由子类实现
java
// 第一步:定义抽象类,包含两类方法
public abstract class Employee {
private String name;
private int age;
// (1)模板方法:封装重复代码(如流程控制),用final修饰(防止子类重写破坏流程)
public final void printIntro() {
System.out.println("姓名:" + name + ",年龄:" + age);
// 第三步:调用模板方法,自动执行重复代码+子类差异化逻辑
printSpecialInfo();
}
// (2)抽象方法:定义差异化逻辑,由子类重写实现
public abstract void printSpecialInfo();
}
// 第二步:子类继承抽象类,重写抽象方法
// 子类1:教师
public class Teacher extends Employee {
private String skill;
@Override
public void printSpecialInfo() {
System.out.println("技能:" + skill);
}
}
// 子类2:咨询师
public class Consultant extends Employee {
private int answerCount;
@Override
public void printSpecialInfo() {
System.out.println("解答问题数:" + answerCount);
}
}
(三) 接口(interface)
- 基础特性:JDK8前仅含"常量(默认public static final) + 抽象方法( 默认 public abstract )";类用 implements 实现,支持多实现,需重写所有抽象方法;
- 核心好处:弥补类单继承不足,支持面向接口编程(灵活切换实现类);
- JDK8+新增方法:默认方法( default, 实现类对象调用)、静态方法(static,接口名调用)、私有方法(private,JDK9+,仅接口内调用);
- 多继承与冲突:接口可多继承,若父接口默认方法同名则冲突;类实现多接口遇同名默认方法,需重写解决,且优先使用父类同名方法。
java
public interface Driver {
// 常量(默认public static final)
String LICENSE_TYPE = "C1";
// 抽象方法(默认public abstract)
void drive();
}
- 接口不能直接实例化,但可通过"接口引用指向实现类对象"支持多态。
java
// 实现多个接口
public class A implements Driver, Singer {
@Override
public void drive() {
System.out.println("开车");
}
@Override
public void sing() {
System.out.println("唱歌");
}
}
// 多态使用
Driver d = new A();
d.drive(); // 执行A的drive()
JDK8+接口新增3种方法
| 方法类型 | 修饰符 | 调用方式 | 作用 |
|---|---|---|---|
| 默认方法 | default | 实现类对象调用 | 提供默认实现,子类可重写 |
| 静态方法 | static | 接口名调用(如 A.test3() ) | 提供工具方法,与实现类解耦 |
| 私有方法 | private | 仅接口内部调用(JDK9+) | 抽取接口内重复代码,隐藏逻辑 |
示例:
java
public interface A {
// 默认方法
default void test1() {
System.out.println("默认方法");
test2(); // 调用私有方法
}
// 私有方法(JDK9+)
private void test2() {
System.out.println("接口内部私有方法");
}
// 静态方法
static void test3() {
System.out.println("静态方法,接口名调用");
}
}
// 调用
A.test3(); // 静态方法调用
A a = new AImpl();
a.test1(); // 默认方法调用
一个接口可继承多个接口(用extends关键字),子类实现该接口时需重写所有父接口的抽象方法。
示例:
java
// 父接口A、B
interface A { void test1(); }
interface B { void test2(); }
// 接口C继承A、B
interface C extends A, B {}
// 实现类需重写test1()和test2()
class CImpl implements C {
@Override
public void test1() {}
@Override
public void test2() {}
}
注意:
- 方法签名冲突 :
- 接口多继承时,若父接口有同名抽象方法,不冲突(仅需重写1次);若有同名默认方法,冲突(不支持多继承);
- 类实现多个接口时,若接口有同名默认方法,实现类需重写该方法解决冲突。
- 父类与接口默认方法优先级 :
类同时继承父类和实现接口,若两者有同名默认方法,优先使用父类的方法。
(四) 内部类(类中类,封装子事物)
内部类是类的五大成分之一(成员变量、方法、构造器、内部类、代码块),用于封装"仅属于外部类的子事物",避免单独设计类造成冗余。
| 类型 | 核心特点与用法 |
|---|---|
| 成员内部类 | 无static,属外部类实例; 需先创建外部类对象,再创建内部类对象( new Outer().new Inner() ); 可直接访问外部类实例/静态成员; 若需明确指向外部类对象,用外部类名 .this (如 Outer.this. 属性 ) |
| 静态内部类 | 有static,属外部类本身;直接通过外部类名创建( new Outer.Inner() ); 仅能访问外部类静态成员,不能直接访问实例成员 |
| 局部内部类 | 定义在方法/代码块/构造器内,作用域仅限当前执行体,了解即可。 |
| 匿名内部类 | 无类名的子类匿名对象;创建后立即生成对象 语法 new 类 / 接口 ( 参数 ){ 重写方法 }; 核心用于作为方法参数传递,简化代码(无需单独定义子类)。 |
java
public class Outer {
// 成员内部类
public class Inner {
public void test() {
System.out.println("成员内部类方法");
}
}
}
java
public class Outer {
public static String schoolName = "黑马";
// 静态内部类
public static class Inner {
public void test() {
System.out.println(schoolName); // 直接访问外部类静态成员
}
}
}
(五) 枚举(特殊类)
枚举用于表示"一组固定的、有限的信息 "(如性别、季节),本质是不可继承的最终类,内部存储常量对象。
java
修饰符 enum 枚举类名 {
常量1, 常量2, 常量3; // 第一行必须是枚举常量(本质是枚举类的对象)
// 其他成员(属性、方法、构造器)
}
注意:
- 枚举类是final 的,
不能被继承;构造器必为private ,对外不能创建对象(仅内部常量是对象);- 编译器自动新增方法:values() (返回所有枚举常量数组)、valueOf(String name) (按名称获取枚举常量);
- 所有枚举类默认继承 java.lang.Enum 类,可直接使用 name() 、ordinal() 等方法。
- 作为方法参数,约束参数值范围(避免传入无效值,比用常量更安全)。
示例:
java
// 仅能传入Gender.BOY或Gender.GIRL
public static void checkGender(Gender gender) {
switch (gender) {
case BOY:
System.out.println("展示男性内容");
break;
case GIRL:
System.out.println("展示女性内容");
break;
}
}
(六) 泛型(参数化类型)
-
核心作用 :
定义类/接口/方法时声明类型变量(如),编译期约束数据类型,避免强制类型转换及异常,提升代码复用性。
-
本质:将具体数据类型作为"参数"传给类型变量(如ArrayList中String是传给 的参数);
-
好处:编译期校验类型,减少运行时异常;无需手动强转,代码更简洁。
1. 三种形式
一、泛型类
修饰符 class 类名<T> (如ArrayList),复用类适配多类型;
(类型变量建议用大写字母:E-元素、T-类型、K-键、V-值)
java
public class MyList<E> {
private E[] array; // 存储E类型的数据
public void add(E e) { ... } // 添加E类型元素
public E get(int index) { ... } // 返回E类型元素
}
// 使用:指定E为String
MyList<String> list = new MyList<>();
list.add("java");
String s = list.get(0); // 无需强转
二、泛型接口(含类型变量的接口)
修饰符 interface 接口名<T> (如Data),实现时指定具体类型;
java
// 泛型接口:定义数据操作规范
public interface Data<E> {
void add(E e);
E get();
}
// 实现接口时指定类型(如E为Student)
public class StudentData implements Data<Student> {
@Override
public void add(Student student) { ... }
@Override
public Student get() { ... }
}
三、泛型方法(含类型变量的方法)
修饰符 <T> 返回值类型 方法名(T param) { ... },适配多类型参数。
java
// 泛型方法:可打印任意类型的数组
public static <T> void printArray(T[] array) {
for (T t : array) {
System.out.print(t + " ");
}
}
// 使用:自动识别类型
Integer[] nums = {1,2,3};
printArray(nums); // 打印1 2 3
String[] strs = {"a","b"};
printArray(strs); // 打印a b
2. 泛型通配符与上下限
| 通配符形式 | 说明 | 示例 |
|---|---|---|
| ? (无限制) | 可接收任意类型 | public void show(List<?> list) { ... } |
| ? extends 类型 | 上限:仅接收"类型及其子类" | List<? extends Car> 可接收 List 、 List |
| ? super 类型 | 下限:仅接收"类型及其父类" | List<? super Car> 可接收 List 、 List |
注意:
- 泛型擦除:泛型仅工作在编译阶段,编译为class 文件后,泛型信息被擦除(如ArrayList< String > 擦除为ArrayList );
- 不支持基本类型:泛型仅接收引用类型(如ArrayList< Integer> 而非ArrayList< int> ),需用包装类替代;
- 静态成员不能使用泛型类的类型变量(静态成员属于类,泛型类型随对象确定)。
(七) 常用API(java.lang包核心)
1. Object类(所有类的祖宗类)
所有类默认继承Object,其方法可被所有对象直接调用,核心方法如下:
| 方法名 | 说明 |
|---|---|
| public String toString() | 返回对象的字符串表示(默认格式:类名 @ 哈希码 ),需子类重写以返回具体内容(如 Student{name=" 张三 "} ) |
| public boolean equals(Object o) | 默认比较对象地址(同 == ),需子类重写以比较内容(如 比较学生的学号和姓名) |
| protected Object clone() | 复制对象并返回新对象,需类实现 Cloneable 接口(否则 抛异常),分浅克隆和深克隆 |
2. 克隆的两种方式
| 类型 | 特点 |
|---|---|
| 浅克隆 | 基本类型直接拷贝,引用类型仅拷贝地址(新对象与原对象共享引用数据) |
| 深克隆 | 基本类型直接拷贝,引用类型创建新对象(新对象与原对象的引用数据完全独立) |
3. Objects工具类
java.util.Objects是静态工具类,提供安全的对象操作方法,避免空指针异常:
| 方法名 | 说明 |
|---|---|
| public static boolean equals(Object a, Object b) | 先判断 a 是否为 null , 再调用 a.equals(b) ,安全比较对象内容 |
| public static boolean isNull(Object obj) | 判断对象是否为 null (为 null 返回 true ) |
| public static boolean nonNull(Object obj) | 判断对象是否不为 null (不为 null 返回 true ) |
4. 包装类(基本类型→对象)
为解决"泛型/集合不支持基本类型"问题,将8种基本类型封装为引用类型(包装类)。
| 基本类型 | 包装类 | 基本类型 | 包装类 |
|---|---|---|---|
| byte | Byte | float | Float |
| short | Short | double | Double |
| int | Integer | char | Character |
| long | Long | boolean | Boolean |
-
自动装箱/拆箱(JDK5+):
- 装箱:基本类型→包装类(如int a = 10; Integer b = a;);
- 拆箱:包装类→基本类型(如Integer b = 10; int a = b;)。
-
常用操作:
- 基本类型→字符串:Integer.toString(123) → "123";
- 字符串→基本类型:Integer.parseInt("123") → 123(或Integer.valueOf("123"))。
5. StringBuilder(可变字符串)
- String是不可变字符串(修改时生成新对象),
- StringBuilder是可变字符串容器,修改效率更高,适合频繁拼接/修改字符串。
| 构造器 | 说明 |
|---|---|
| public StringBuilder() | 创建空白可变字符串(初始容量16) |
| public StringBuilder(String str) | 创建含指定字符串的可变对象 |
| 方法名 | 说明 |
|---|---|
| public StringBuilder append(任意类型) | 添加数据并返回自身(支持链式调用) |
| public StringBuilder reverse() | 反转字符串内容 |
| public int length() | 返回字符串长度 |
| public String toString() | 转为 String 类型 |
注意::
- StringBuffer 与StringBuilder 用法一致
- StringBuffer 是线程安全的(效率低)
- StringBuilder 线程不安全(效率高,推荐单线程使用)
6. StringJoiner(JDK8+,简化拼接)
- StringJoiner是 StringBuilder 的增强工具
- 专为"分隔符拼接"设计,代码更简洁(如拼接数组为[11,22,33])
| 构造器 | 说明 |
|---|---|
| public StringJoiner(CharSequence delimiter) | 指定间隔符(如 , ) |
| public StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) | 指定间隔符、前缀(如 [ )、后缀(如 ] ) |
| 方法名 | 说明 |
|---|---|
| public StringJoiner add(CharSequence str) | 添加内容并返回自身 |
| public int length() | 返回拼接后字符串长度 |
| public String toString() | 返回拼接结果( String 类型) |
示例:
java
import java.util.StringJoiner;
public class Test {
public static void main(String[] args) {
int[] arr = {11,22,33};
StringJoiner sj = new StringJoiner(",", "[", "]"); // 间隔符, 前缀[, 后缀]
for (int num : arr) {
sj.add(String.valueOf(num));
}
System.out.println(sj); // 输出[11,22,33]
}
}
(八) 基础工具类
1. Math(数学工具类)
全静态方法,用于常见数学运算,无需创建对象。
| 方法名 | 说明 |
|---|---|
| abs(int/double a) | 获取绝对值(结果非负) |
| ceil(double a) | 向上取整(返回不小于a的最小整数) |
| floor(double a) | 向下取整(返回不大于a的最大整数) |
| round(float/double a) | 四舍五入(返回long/int) |
| max(int a, int b) | 获取两数最大值(min为最小值) |
| pow(double a, double b) | 计算a的b次幂 |
| random() | 生成[0.0,1.0)的随机double值 |
2. System(系统工具类)
代表当前Java程序所在系统,提供系统级操作。
| 方法名 | 说明 | 应用场景 |
|---|---|---|
| exit(int status) | 终止Java虚拟机(0为正常退出,非0异常) | 手动结束程序 |
| currentTimeMillis() | 返回当前系统时间毫秒值(1970-01-01起) | 程序性能分析(计算执行耗时) |
示例:性能分析
java
long start = System.currentTimeMillis();
// 执行耗时操作(如循环)
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) / 1000.0 + "s");
3. Runtime(运行环境类)
代表程序运行环境,单例类(仅一个实例),通过Runtime.getRuntime()获取实例。
| 方法名 | 说明 |
|---|---|
| getRuntime() | 获取当前Java应用的Runtime实例 |
| availableProcessors() | 返回虚拟机可用处理器数(如8核返回8) |
| totalMemory() / freeMemory() | 返回虚拟机总内存/可用内存(字节) |
| exec(String command) | 启动外部程序(如 exec("notepad.exe") 打开记事本) |
(九) BigDecimal(高精度小数)
解决浮点型运算(如0.1+0.2=0.30000000000000004)的精度失真问题。
构造器选择:
- BigDecimal.valueOf(double val)(内部转为 String,避免失真)
- new BigDecimal(String val)(直接传入字符串,如new BigDecimal("0.1"))
| 方法名 | 说明 |
|---|---|
| add(BigDecimal b) | 加法 |
| subtract(BigDecimal b) | 减法 |
| multiply(BigDecimal b) | 乘法 |
| divide(BigDecimal b, int scale, RoundingMode mode) | 除法(指定精度和舍入模式) |
| doubleValue() | 转为double类型 (最终需返回基本类型时用) |
示例:
java
BigDecimal a = BigDecimal.valueOf(0.1);
BigDecimal b = BigDecimal.valueOf(0.2);
BigDecimal sum = a.add(b); // 0.3
System.out.println(sum.doubleValue()); // 输出0.3
(十) 日期与时间API(JDK8+)
特点:不可变对象 (修改返回新对象)、线程安全、支持纳秒精度。
| 类名 | 功能 | 核心操作 |
|---|---|---|
| LocalDate/LocalTime | 仅年月日/仅时分秒 | now()(当前)、 of()(指定)、 plus/minus (增减) |
| LocalDateTime | 年月日+时分秒 | 支持格式化( format )、解析 ( parse )、字段修改 |
| ZonedDateTime | 带时区时间(如Asia/Shanghai) | now(ZoneId.of("Asia/Shanghai")) 获指定时区时间 |
| Instant | 时间戳(替代Date) | now()(当前标准时间) |
| DateTimeFormatter | 格式化/解析(替代 SimpleDateFormat) | ofPattern("yyyy-MM-dd HH:mm:ss") |
| Period/Duration | 时间间隔计算 | Period.between (LocalDate间隔,年月日)、 Duration.between (时间间隔,时分秒纳秒) |
| 操作类型 | 方法示例 | 说明 |
|---|---|---|
| 获取字段 | ldt.getYear() 、 ldt.getHour() | 获取年、小时等 |
| 修改字段 | ldt.withYear(2025) | 修改年为2025,返回新对象 |
| 增减时间 | ldt.plusDays(3) 、 ldt.minusHours(2) | 加3天、减2小时,返回新对象 |
| 比较 | ldt1.isBefore(ldt2) | 判断ldt1是否在ldt2之前 |
| 格式化 | ldt.format(formatter) | 转为指定格式字符串 |
| 解析 | LocalDateTime.parse("2024-05-20 14:30:00", formatter) | 字符串转LocalDateTime |
| 类名 | 功能 | 核心方法 |
|---|---|---|
| Period | 计算两个LocalDate的间隔(年月日) | Period.between(startDate, endDate) → 获取年差、月差、日差 |
| Duration | 计算时间间隔(时分秒纳秒) | Duration.between(startTime, endTime) → 转为天、小时、秒等 |
(十一) Arrays(数组工具类)
全静态方法,用于数组的常用操作(遍历、拷贝、排序等)
| 方法名 | 说明 |
|---|---|
| toString( 类型 [ ] arr) | 将数组转为字符串 (如 [1,2,3] ) |
| copyOf( 类型 [ ] arr, int newLen) | 拷贝数组,指定新长度 |
| copyOfRange( 类型 [ ] arr, int from, int to) | 拷贝指定范围(包前不包后) |
| sort( 类型 [ ] arr) | 数组排序(默认升序,基本类型) |
| sort(T[ ] arr, Comparator<? super T> c) | 对象数组自定义排序 |
(十二) Lambda表达式(简化匿名内部类)
前提 :仅简化函数式接口 (仅1个抽象方法,注@FunctionalInterface);
语法: (抽象方法形参列表) -> { 抽象方法体代码 }
省略规则(进一步简化):
- 形参类型可省略;
- 若仅一个形参,() 可省略;
- 若方法体仅1行代码,{} 和; 可省略,若为return 语句,return 也需省略。
示例:
java
// 匿名内部类
Arrays.sort(students, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
return s1.getAge() - s2.getAge();
}
});
// Lambda简化(省略类型、大括号、return)
Arrays.sort(students, (s1, s2) -> s1.getAge() - s2.getAge());
当Lambda体仅调用一个方法,且参数传递一致时,可用方法引用替代。
| 引用类型 | 格式 | 示例 |
|---|---|---|
| 静态方法引用 | 类名 :: 静态方法名 | Math::abs (替代 (x)->Math.abs(x) ) |
| 实例方法引用 | 对象名 :: 实例方法名 | str::length (替代 ()->str.length() ) |
| 特定类型方法引用 | 类型 :: 实例方法名 | String::compareTo (替代 (s1,s2)->s1.compareTo(s2) ) |
| 构造器引用 | 类名 ::new | Student::new (替代 (name,age)->new Student(name,age) ) |
(十三) 异常(程序错误处理)
异常是程序编译或运行时出现的错误(如除以0、数组索引越界),Java将其封装为对象(继承 Throwable)。
一、异常体系(核心层级)
Throwable(顶层)
├─ Error(系统级错误,无需处理):如内存溢出、虚拟机错误,程序员无需关注
└─ Exception(程序级异常,需处理)
├─ 运行时异常(RuntimeException子类):编译不报错,运行时可能出现
│ ├─ ArrayIndexOutOfBoundsException(数组索引越界)
│ ├─ ArithmeticException(算术异常,如除以0)
│ └─ NullPointerException(空指针异常)
└─ 编译时异常(非RuntimeException子类):编译阶段报错,必须处理
├─ ParseException(日期解析异常)
└─ IOException(IO异常)
二、异常的处理方式
- 抛出(throws ):
方法上声明异常,抛给调用者处理,自身不处理。
java
public void 方法名() throws 异常1, 异常2 {...}
- 捕获异常(try-catch):
监控异常代码,捕获后自行处理。
java
try {
// 可能出现异常的代码(监控区)
} catch (异常类型1 变量名) {
// 异常1的处理逻辑(如打印日志)
} catch (异常类型2 变量名) {
// 异常2的处理逻辑
} catch (Exception e) { // 推荐:用Exception捕获所有异常(兜底)
e.printStackTrace(); // 打印异常堆栈(查bug关键)
}
三、自定义异常
- 运行时异常:
继承RuntimeException,重写构造器,用throw new 自定义异常(消息)抛出。(编译不报错);
java
// 自定义运行时异常:年龄不合法
public class AgeIllegalException extends RuntimeException {
// 无参构造器
public AgeIllegalException() {}
// 带消息的构造器
public AgeIllegalException(String message) {
super(message);
}
}
// 使用
public static void checkAge(int age) {
if (age < 18 || age > 60) {
throw new AgeIllegalException("年龄必须18-60岁"); // 抛出异常
}
}
- 编译时异常:
继承Exception,重写构造器,用 throw new 自定义异常(消息) 抛出,且方法需用 throws 声明。(编译报错,提醒强)。
java
// 自定义编译时异常:年龄不合法
public class AgeIllegalException extends Exception {
public AgeIllegalException() {}
public AgeIllegalException(String message) {
super(message);
}
}
// 使用:方法需声明抛出
public static void checkAge(int age) throws AgeIllegalException {
if (age < 18 || age > 60) {
throw new AgeIllegalException("年龄必须18-60岁");
}
}
四、异常的核心作用
- 定位bug:异常堆栈( printStackTrace() )提供错误代码行和原因,是查bug的关键;
- 传递执行状态:作为方法的"特殊返回值",通知上层调用者底层执行失败(如"年龄不合法")。
(十四) File类(文件/文件夹操作)
- 核心定位:操作文件/文件夹本身(创建、删除、获取信息),不能读写文件内容。
- 路径分类 :
- 绝对路径(盘符开头,如 D:/test.txt )
- 相对路径(无盘符,默认当前工程/模块下)
| 构造器 | 说明 |
|---|---|
| File(String pathname) | 根据文件路径创建对象(路径可存在/不存在) |
| File(String parent, String child) | 父路径+子路径创建对象 |
| File(File parent, String child) | 父路径File对象+子路径创建对象 |
| 方法名 | 说明 |
|---|---|
| exists() | 判断路径是否存在(存在返回 true ) |
| isFile() | 判断是否为文件(是返回 true ) |
| isDirectory() | 判断是否为文件夹(是返回 true ) |
| getName() | 获取文件/文件夹名称(含后缀) |
| length() | 获取文件大小(字节数,文件夹返回0) |
| lastModified() | 获取最后修改时间(毫秒值,1970年起) |
| getAbsolutePath() | 获取绝对路径 |
| 方法名 | 说明 | 注意事项 |
|---|---|---|
| createNewFile () | 创建空文件(成功返回 true ) | 需处理 IOException ,路径不存在会报错 |
| mkdir() | 创建一级文件夹 | 父文件夹不存在则创建失败 |
| mkdirs() | 创建多级文件夹(推荐) | 父文件夹不存在会自动创建 |
| delete() | 删除文件/空文件夹(成功返回 true ) | 非空文件夹无法直接删除,删除后不进回收站 |
| 方法名 | 说明 | 注意事项 |
|---|---|---|
| list() | 返回文件夹下一级文件/文件夹名称数组 | 主调是文件或路径不存在时返回 null |
| listFiles() | 返回文件夹下一级文件/文件夹的 File数组 | 空文件夹返回长度为0的数组,无权限访问返回 null |