> 技术文档 > Java API (二):从 Object 类到正则表达式的核心详解

Java API (二):从 Object 类到正则表达式的核心详解


个人主页-爱因斯晨

Java API 详解 (一)

互三啦,兄弟们!!加油加油!!

Java API (二):从 Object 类到正则表达式的核心详解

一、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; } @Override public 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()方法。
@Overridepublic boolean equals(Object obj) { // 1. 自反性:自身比较返回true if (this == obj) return true; // 2. 非空判断:传入null返回false if (obj == null) return false; // 3. 类型判断:类型不同返回false if (getClass() != obj.getClass()) return false; // 4. 强转并比较属性 Person other = (Person) obj; return age == other.age && Objects.equals(name, other.name);}// 重写hashCode()@Overridepublic 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()); // 输出:Person System.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; } @Override public Student clone() throws CloneNotSupportedException { return (Student) super.clone(); } // getter和setter public 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; } @Override public Address clone() throws CloneNotSupportedException { return (Address) super.clone(); } // getter和setter public 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; } @Override public User clone() throws CloneNotSupportedException { User user = (User) super.clone(); // 对引用类型字段进行克隆 user.address = this.address.clone(); return user; } // getter和setter public 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和setter public 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)); // true System.out.println(Objects.equals(a, c)); // false(不会抛空指针) // 判空方法 System.out.println(Objects.isNull(c)); // true System.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); }}