Java API (二):从 Object 类到正则表达式的核心详解
个人主页-爱因斯晨
Java API 详解 (一)
互三啦,兄弟们!!加油加油!!
一、Object 类
Object类是 Java 语言中唯一没有父类的类,所有类都直接或间接继承自它,这意味着任何 Java 对象都能调用 Object 类中的方法。
1. 核心方法解析
- toString():返回对象的字符串表示。默认实现为类名@哈希值的十六进制,实际开发中通常会重写该方法,以返回对象的具体信息。例如:
class Person {private String name;private int age;// 构造方法public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}// 测试代码
public class TestToString {public static void main(String[] args) {Person p = new Person("张三", 20);System.out.println(p); // 直接打印对象会调用toString(),输出:Person{name='张三', age=20}}
}
- equals():用于比较两个对象是否相等。默认实现是比较对象的内存地址(即this == obj),但在实际业务中,我们常重写该方法以实现自定义的相等逻辑。重写时需遵循对称性、传递性等原则,且建议同时重写hashCode()方法。
@Override
public boolean equals(Object obj) {// 1. 自反性:自身比较返回trueif (this == obj) return true;// 2. 非空判断:传入null返回falseif (obj == null) return false;// 3. 类型判断:类型不同返回falseif (getClass() != obj.getClass()) return false;// 4. 强转并比较属性Person other = (Person) obj;return age == other.age && Objects.equals(name, other.name);
}// 重写hashCode()
@Override
public int hashCode() {return Objects.hash(name, age);
}
-
hashCode():返回对象的哈希码值,主要用于哈希表(如 HashMap)等数据结构。关键原则是:若两个对象通过equals()比较返回 true,则它们的hashCode()必须相等;若hashCode()不相等,则equals()一定返回 false。
-
getClass():返回对象的运行时类(Class 对象),可用于反射机制、判断对象具体类型等场景。例如:
public class TestGetClass {public static void main(String[] args) {Person p = new Person("李四", 25);Class<?> clazz = p.getClass();System.out.println("类名:" + clazz.getSimpleName()); // 输出:PersonSystem.out.println("全限定名:" + clazz.getName()); // 输出:包名.Person}
}
- finalize():该方法在垃圾回收器回收对象前调用,但 JDK 9 起已被标记为过时,不建议使用,资源释放可通过 try-with-resources 等机制实现。
二、对象克隆与 Objects 工具类
在实际开发中,有时需要创建一个与原对象内容相同的新对象,这就涉及到克隆机制;而 Objects 工具类则为对象操作提供了更多便捷方法。
1. 克隆机制
克隆分为浅克隆和深克隆两种,它们的核心区别在于对引用类型字段的处理方式。
- 浅克隆:基本数据类型的字段会被复制,引用类型的字段仅复制引用地址(新对象与原对象共享引用类型数据)。实现步骤为:让类实现Cloneable接口,并重写Object类的clone()方法。示例:
class Student implements Cloneable {private String name; // 引用类型private int age; // 基本类型private Teacher teacher; // 引用类型public Student(String name, int age, Teacher teacher) {this.name = name;this.age = age;this.teacher = teacher;}@Overridepublic Student clone() throws CloneNotSupportedException {return (Student) super.clone();}// getter和setterpublic String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }public Teacher getTeacher() { return teacher; }public void setTeacher(Teacher teacher) { this.teacher = teacher; }
}class Teacher {private String subject;public Teacher(String subject) { this.subject = subject; }public String getSubject() { return subject; }public void setSubject(String subject) { this.subject = subject; }
}// 浅克隆测试
public class TestShallowClone {public static void main(String[] args) throws CloneNotSupportedException {Teacher t = new Teacher("数学");Student s1 = new Student("王五", 18, t);Student s2 = s1.clone();// 基本类型字段独立s2.setAge(19);System.out.println(s1.getAge()); // 18(不受影响)// 引用类型字段共享s2.getTeacher().setSubject("语文");System.out.println(s1.getTeacher().getSubject()); // 语文(受影响)}
}
- 深克隆:不仅复制基本类型字段,还会递归复制所有引用类型字段(新对象与原对象的引用类型数据完全独立)。实现方式有两种:
class Address implements Cloneable {private String city;public Address(String city) { this.city = city; }@Overridepublic Address clone() throws CloneNotSupportedException {return (Address) super.clone();}// getter和setterpublic String getCity() { return city; }public void setCity(String city) { this.city = city; }
}class User implements Cloneable {private String username;private Address address;public User(String username, Address address) {this.username = username;this.address = address;}@Overridepublic User clone() throws CloneNotSupportedException {User user = (User) super.clone();// 对引用类型字段进行克隆user.address = this.address.clone();return user;}// getter和setterpublic String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public Address getAddress() { return address; }public void setAddress(Address address) { this.address = address; }
}// 深克隆测试
public class TestDeepClone {public static void main(String[] args) throws CloneNotSupportedException {Address addr = new Address("北京");User u1 = new User("赵六", addr);User u2 = u1.clone();u2.getAddress().setCity("上海");System.out.println(u1.getAddress().getCity()); // 北京(不受影响)}
}
import java.io.*;class Product implements Serializable {private String name;private double price;public Product(String name, double price) {this.name = name;this.price = price;}// 深克隆方法public Product deepClone() throws IOException, ClassNotFoundException {// 序列化ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);oos.writeObject(this);// 反序列化ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());ObjectInputStream ois = new ObjectInputStream(bis);return (Product) ois.readObject();}// getter和setterpublic String getName() { return name; }public void setName(String name) { this.name = name; }public double getPrice() { return price; }public void setPrice(double price) { this.price = price; }
}
-
方式一:嵌套克隆
-
方式二:序列化实现
2. Objects 工具类
java.util.Objects是 JDK 7 新增的工具类,提供了一系列静态方法用于对象的安全操作,能有效避免空指针异常。常用方法代码示例:
public class TestObjects {public static void main(String[] args) {String a = "abc";String b = "abc";String c = null;// equals方法System.out.println(Objects.equals(a, b)); // trueSystem.out.println(Objects.equals(a, c)); // false(不会抛空指针)// 判空方法System.out.println(Objects.isNull(c)); // trueSystem.out.println(Objects.nonNull(a)); // true// 非空校验try {Objects.requireNonNull(c, "参数不能为null");} catch (NullPointerException e) {System.out.println(e.getMessage()); // 参数不能为null}// 哈希码计算int hash = Objects.hashCode(a, 123);System.out.println(hash);}
}
三、BigInteger
Java 中的基本数据类型long有取值范围限制(-2^63 到 2^63-1),当需要处理超过该范围的整数时,就需要使用BigInteger类。
1. 基本特性
BigInteger位于java.math包下,它可以表示任意大小的整数,不受基本数据类型取值范围的限制。
2. 常用操作代码示例
import java.math.BigInteger;public class TestBigInteger {public static void main(String[] args) {// 创建BigInteger对象BigInteger bigNum1 = new BigInteger("123456789012345678901234567890");BigInteger bigNum2 = new BigInteger("987654321098765432109876543210");// 加法BigInteger sum = bigNum1.add(bigNum2);System.out.println("和:" + sum);// 减法BigInteger difference = bigNum2.subtract(bigNum1);System.out.println("差:" + difference);// 乘法BigInteger product = bigNum1.multiply(bigNum2);System.out.println("积:" + product);// 除法(需确保能整除)BigInteger quotient = bigNum2.divide(new BigInteger("10"));System.out.println("商:" + quotient);// 取余BigInteger remainder = bigNum1.remainder(new BigInteger("7"));System.out.println("余数:" + remainder);// 比较大小int compareResult = bigNum1.compareTo(bigNum2);if (compareResult < 0) {System.out.println("bigNum1 < bigNum2");} else if (compareResult > 0) {System.out.println("bigNum1 > bigNum2");} else {System.out.println("bigNum1 = bigNum2");}}
}
四、BigDecimal
float和double类型的浮点数在运算时可能会出现精度丢失问题,而BigDecimal类则提供了高精度的小数运算支持。
1. 精度问题示例
public class TestBigDecimalProblem {public static void main(String[] args) {System.out.println(0.1 + 0.2); // 输出0.30000000000000004(精度丢失)}
}
2. BigDecimal 常用操作代码
import java.math.BigDecimal;
import java.math.RoundingMode;public class TestBigDecimal {public static void main(String[] args) {// 推荐使用String构造方法BigDecimal num1 = new BigDecimal("0.1");BigDecimal num2 = new BigDecimal("0.2");// 加法BigDecimal sum = num1.add(num2);System.out.println("0.1 + 0.2 = " + sum); // 0.3// 减法BigDecimal difference = num2.subtract(num1);System.out.println("0.2 - 0.1 = " + difference); // 0.1// 乘法BigDecimal product = num1.multiply(new BigDecimal("2"));System.out.println("0.1 * 2 = " + product); // 0.2// 除法(指定舍入模式)BigDecimal quotient = new BigDecimal("1").divide(new BigDecimal("3"), 2, RoundingMode.HALF_UP);System.out.println("1 / 3 = " + quotient); // 0.33// 设置小数位数BigDecimal num3 = new BigDecimal("3.1415926");BigDecimal scaledNum = num3.setScale(2, RoundingMode.HALF_UP);System.out.println("保留2位小数:" + scaledNum); // 3.14}
}
五、正则表达式
正则表达式是一种用于描述字符串模式的工具,它可以高效地进行字符串的匹配、查找、替换等操作。
1. 常用元字符及示例
元字符 | 含义 | 示例 | 匹配结果 |
---|---|---|---|
. | 匹配任意单个字符(除换行) | a.b | aab、acb、a1b |
* | 匹配前面子表达式 0 次或多次 | ab*c | ac、abc、abbc |
+ | 匹配前面子表达式 1 次或多次 | ab+c | abc、abbc |
? | 匹配前面子表达式 0 次或 1 次 | ab?c | ac、abc |
[] | 字符集 | [abc] | a、b、c |
() | 分组 | (ab)+ | ab、abab |
| | 或 | a|b | a、b |
^ | 开始位置 | ^abc | abc(字符串开头) |
$ | 结束位置 | abc$ | abc(字符串结尾) |
\d | 数字 | \d{3} | 123、456 |
\w | 字母、数字、下划线 | \w+ | hello、user123 |
2. 正则表达式在 Java 中的使用代码
import java.util.regex.Matcher;
import java.util.regex.Pattern;public class TestRegex {public static void main(String[] args) {// 1. 匹配手机号(11位,以1开头,第二位3-9)String phone = "13800138000";boolean isPhone = phone.matches("1[3-9]\\d{9}");System.out.println("是否为手机号:" + isPhone);// 2. 匹配邮箱(增强版:支持多级域名和下划线)String email = "test.user_name@mail.example.co.uk";boolean isEmail = email.matches("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");System.out.println("是否为邮箱:" + isEmail);// 3. 拆分字符串(处理连续分隔符)String str = "apple,,banana;;orange grape";String[] fruits = str.split("[,;\\s]+"); // +表示匹配1次或多次System.out.println("\n拆分结果:");for (String fruit : fruits) {System.out.println(fruit);}// 4. 替换字符串(按规则替换)String text = "Java123Script456Python789C";// 替换数字为下划线String replacedText1 = text.replaceAll("\\d+", "_");System.out.println("\n替换数字为下划线:" + replacedText1);// 只保留字母String replacedText2 = text.replaceAll("[^a-zA-Z]", "");System.out.println("只保留字母:" + replacedText2);// 5. 提取特定内容(分组提取)String log = "用户id:10086,用户名:张三,年龄:25;用户id:10010,用户名:李四,年龄:30";Pattern userPattern = Pattern.compile("用户id:(\\d+),用户名:(\\w+),年龄:(\\d+)");Matcher userMatcher = userPattern.matcher(log);System.out.println("\n提取用户信息:");while (userMatcher.find()) {String id = userMatcher.group(1); // 第1个分组String name = userMatcher.group(2); // 第2个分组String age = userMatcher.group(3); // 第3个分组System.out.println("ID:" + id + ", 姓名:" + name + ", 年龄:" + age);}// 6. 复杂模式验证(身份证号)String idCard = "110101199001011234";boolean isIdCard = idCard.matches("[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]");System.out.println("\n是否为身份证号:" + isIdCard);}
}