Java 黑马程序员学习笔记(进阶篇4)
常用的 API
1. Math
方法声明 | 说明 |
---|---|
public static int abs(int a) | 返回参数的绝对值 |
public static double ceil(double a) | 返回大于或等于参数的最小double 值,等于一个整数 |
public static double floor(double a) | 返回小于或等于参数的最大double 值,等于一个整数 |
public static int round(float a) | 按照四舍五入返回最接近参数的int |
public static int max(int a, int b) | 返回两个int 值中的较大值 |
public static int min(int a, int b) | 返回两个int 值中的较小值 |
public static double pow(double a, double b) | 返回a 的b 次幂的值 |
public static double random() | 返回值为double 的正值,范围 [0.0, 1.0) |
2. System
方法名 | 说明 |
---|---|
public static void exit(int status) | 终止当前运行的 Java 虚拟机,非零表示异常终止 |
public static long currentTimeMillis() | 返回当前时间(以毫秒为单位) |
3. Runtime
Runtime 表示当前虚拟机的运行环境
方法名 | 说明 |
---|---|
public static Runtime getRuntime() | 当前系统的运行环境对象 |
public void exit(int status) | 停止虚拟机 |
public int availableProcessors() | 获得 CPU 的线程数 |
public long maxMemory() | JVM 能从系统中获取总内存大小(单位 byte) |
public long totalMemory() | JVM 已经从系统中获取总内存大小(单位 byte) |
public long freeMemory() | JVM 剩余内存大小(单位 byte) |
public Process exec(String command) | 运行 cmd 命令 |
4. Object
java.lang.Object
是 Java 中所有类的直接或间接父类(除接口和数组外),任何类都继承了 Object 的方法。它包含 11 个核心方法,以下是最常用的 5 个:
① toString()
方法
- 默认行为:返回对象的字符串表示,格式为
类全限定名@哈希码的十六进制
(如com.Student@1b6d3586
),无实际业务意义。 - 重写目的:通常重写为返回对象的属性信息,方便打印和调试。
② equals(Object obj)
方法
- 默认行为:等价于
==
,比较两个对象的内存地址(是否为同一实例)。 - 重写目的:判断两个对象的逻辑相等(属性值是否相同),如两个
Student
对象姓名和年龄相同则认为相等。
- 注意:重写
equals()
必须同时重写hashCode()
(否则会导致 HashMap 等集合存储异常)。
③ clone()
方法
- 作用:创建对象的副本(克隆),默认实现为浅克隆。
- 浅克隆:基本类型属性直接复制,引用类型属性复制引用(新对象与原对象共享引用对象)。
- 深克隆:引用类型属性也会被重新创建(完全独立),需重写
clone()
或使用工具类(如 Gson、Jackson)。 - 使用条件:类必须实现
Cloneable
接口(标记接口,无实际方法),否则抛CloneNotSupportedException
。
这段代码是重写clone()
方法实现深克隆的典型案例,我们一步步拆解它的作用和原理:
protected Object clone() throws CloneNotSupportedException {// 1. 获取原对象的data数组引用int[] data = this.data;// 2. 创建一个新的int数组,长度和原数组一致int[] newData = new int[data.length];// 3. 把原数组的元素逐个复制到新数组(深拷贝数组)for (int i = 0; i < data.length; i++) {newData[i] = data[i];}// 4. 调用父类(Object)的clone()方法,得到浅克隆的User对象User u = (User) super.clone();// 5. 把新数组赋值给克隆对象的data成员(替换浅克隆的引用)u.data = newData;// 6. 返回深克隆后的对象return u;
}
(1) 默认情况下,Object
的clone()
是浅克隆:对于基本类型成员(如 int、double)会直接复制值;但对于引用类型成员(如数组、对象),只会复制引用(即新对象和原对象的引用类型成员指向同一块内存)。而这段代码的目的是:实现深克隆,让克隆出的User
对象和原对象的data
数组完全独立(不共享同一块内存)。
(2) 关键逻辑:
Q1:为什么使用 this.data?
A1:this
是 Java 中的关键字,代表当前对象的实例。这里的 this.data
明确表示 “当前正在被克隆的 User
对象的 data
成员变量”。
Q2:为什么还要使用浅克隆,为什么不直接返回 newData?
A2:先明确:我们的目标是 “克隆 User 对象”,不是 “克隆 data 数组”,
- 我们要实现的是:创建一个新的 User 对象,这个新对象的
name
、age
和原对象相同,data
数组也和原对象相同但完全独立(不共享内存)。这才叫 “克隆 User 对象”。 - 而
newData
只是一个int[]
数组 —— 返回newData
只能得到一个数组,根本不是User
类型的对象,完全满足不了 “克隆 User” 的需求。
5. Objects
Objects
是 Java 提供的对象操作工具类(位于 java.util
包下),封装了一系列静态方法,用于更安全、便捷地操作对象(核心解决 “空指针异常” 等问题)。
方法签名 | 说明 |
---|---|
public static boolean equals(Object a, Object b) | 先做非空判断,再比较两个对象是否相等(避免 a.equals(b) 因 a 为 null 抛异常) |
public static boolean isNull(Object obj) | 判断对象是否为 null ,若为 null 返回 true ,否则返回 false |
public static boolean nonNull(Object obj) | 判断对象是否不为 null ,与 isNull 结果相反(obj 非空返回 true ) |
6. BigInteger
(1) BigInteger
位于 java.math
包下,是用于处理超出基本数据类型范围的大整数的类。
- 基本数据类型(如
int
最大为2^31-1
,long
最大为2^63-1
)无法表示的超大整数,需用BigInteger
存储和计算。 BigInteger
可以表示任意精度的整数,理论上仅受内存限制。
(2) 常用的构造方法
通过字符串参数创建(推荐,避免整数字面量超出范围):
import java.math.BigInteger;// 创建 BigInteger 对象
BigInteger num1 = new BigInteger("12345678901234567890"); // 超大整数,超出 long 范围
BigInteger num2 = new BigInteger("98765432109876543210");
(3) 算术运算
方法 | 说明 | 示例(num1 = 10, num2 = 3) |
---|---|---|
add(BigInteger val) | 加法 | num1.add(num2) → 13 |
subtract(BigInteger val) | 减法 | num1.subtract(num2) → 7 |
multiply(BigInteger val) | 乘法 | num1.multiply(num2) → 30 |
divide(BigInteger val) | 除法(整除) | num1.divide(num2) → 3(10/3=3) |
remainder(BigInteger val) | 取余 | num1.remainder(num2) → 1 |
divideAndRemainder(BigInteger val) | 除法 + 取余 | 返回数组 [商, 余数] → [3,1] |
(4) 其他常用方法
方法 | 说明 |
---|---|
intValue() | 转换为 int 类型(超出范围会丢失精度) |
longValue() | 转换为 long 类型(超出范围会丢失精度) |
7. BigDecima
BigDecimal 位于 java.math 包下,是专门处理高精度小数的类,解决 float/double 因二进制存储导致的 “精度丢失” 问题(如 0.1 + 0.2 ≠ 0.3)。
- 适用场景:金融计算(金额、税率)、科学测量(高精度小数)等需 “绝对精确” 的场景;
- 核心优势:支持任意精度的小数表示,可手动控制计算精度和舍入规则。
(1) 创建 BigDecimal 对象
① 推荐创建方式(避免精度丢失),必须用 String 构造,严禁用 double 构造(double 本身存在精度误差,会传递给 BigDecimal):
import java.math.BigDecimal;
// 1. String 构造(最推荐,无精度丢失)
BigDecimal money1 = new BigDecimal("19.9"); // 正确:表示精确的 19.9
BigDecimal rate = new BigDecimal("0.06"); // 正确:表示精确的 0.06
// 2. 常量构造(常用简单值)
BigDecimal zero = BigDecimal.ZERO; // 表示 0
BigDecimal one = BigDecimal.ONE; // 表示 1
BigDecimal ten = BigDecimal.TEN; // 表示 10
// 3. BigInteger 构造(需指定小数位数)
BigDecimal num = new BigDecimal(BigInteger.valueOf(123), 2); // 123 → 1.23(2位小数)
② 严禁的创建方式(精度丢失示例)
// 错误:double 本身是 0.1 的近似值(二进制无法精确表示 0.1)
BigDecimal wrong = new BigDecimal(0.1);
System.out.println(wrong); // 输出:0.1000000000000000055511151231257827021181583404541015625
(2) 核心操作方法(均返回新对象,原对象不可变!)
BigDecimal 是不可变类,所有运算方法都会返回新的 BigDecimal 对象,原对象值不会改变。
方法签名 | 说明 | 示例(money1=19.9,rate=0.06) |
---|---|---|
add(BigDecimal val) | 加法 | money1.add(rate) → 19.96 |
subtract(BigDecimal val) | 减法 | money1.subtract(rate) → 19.84 |
multiply(BigDecimal val) | 乘法(无需指定精度) | money1.multiply(rate) → 1.194 |
divide(BigDecimal val, int scale, int roundingMode) | 除法(需指定:小数位数 + 舍入模式) | money1.divide(rate, 2, BigDecimal.ROUND_HALF_UP) → 331.67(19.9÷0.06≈331.666...,保留 2 位小数四舍五入) |
除法避坑:不指定精度会抛异常
若直接调用 divide(BigDecimal val),当结果无法整除时(如 1÷3),会抛出 ArithmeticException,必须显式指定 scale(保留小数位数)和 roundingMode(舍入模式)。