Object类_13

Object类

Object 类是 Java 中所有类的根类,所有类都直接或间接继承自 Object 类。它定义了一些通用的方法,这些方法可以被所有 Java 对象使用。

其中包括public boolean equals(Object obj)public int hashCode()public String toString()protected Object clone() throws CloneNotSupportedExceptionpublic final Class<?> getClass()public final void notify()public final void notifyAll()public final void wait() throws InterruptedExceptionpublic final void wait(long timeout) throws InterruptedExceptionpublic final void wait(long timeout, int nanos) throws InterruptedExceptionprotected void finalize() throws Throwable方法。

equal方法

==操作运算符

  • == 是一个操作运算符,用于比较两个操作数的值。它的具体行为取决于操作数的类型。== 可以用于基本数据类型和引用数据类型

  • 当 == 用于基本数据类型(如 int、char、boolean 等)时,它比较的是两个操作数的值是否相等

  • 当 == 用于引用数据类型(如对象、数组等)时,它比较的是两个引用是否指向同一个对象(即内存地址是否相同)

  • 对于字符串字面量(如 "Hello"),Java 会将其存储在字符串常量池中

  • 如果两个字符串字面量内容相同,它们会指向常量池中的同一个对象

    String str1 = "Hello";
    String str2 = "Hello";
    
    System.out.println(str1 == str2); // true
    
  • 当使用 new 关键字创建字符串时,无论字符串常量池中是否存在相同内容的字符串,都会在堆内存中创建一个新的字符串对象

    String str1 = new String("Hello");
    String str2 = new String("Hello");
    
    System.out.println(str1 == str2); // false
    
  • 直接赋值 与 new 关键字的比较

    String str1 = "Hello"; // 直接赋值
    String str2 = new String("Hello"); // 使用 new 关键字
    
    System.out.println(str1 == str2); // false
    
    //str1 指向字符串常量池中的对象。
    //str2 指向堆内存中的新对象。
    //因此,str1 == str2 为 false
    
  • 字符串常量池

    字符串常量池:存储所有通过直接赋值创建的字符串

    intern() 方法:可以将字符串对象添加到常量池中,并返回常量池中的引用

    String str1 = new String("Hello").intern();
    String str2 = "Hello";
    
    System.out.println(str1 == str2); // true
    
  • 对于包装类(如 Integer、Double 等),== 的行为可能因自动装箱和拆箱而有所不同

    Integer x = 100; // 自动装箱
    Integer y = 100; // 自动装箱
    
    System.out.println(x == y); // 输出 true
    
    Integer a = 200; // 自动装箱
    Integer b = 200; // 自动装箱
    
    System.out.println(a == b); // 输出 false
    
  • 在这个例子中,x 和 y 都被自动装箱为 Integer 对象。由于 Integer 类在 -128 到 127 之间的值会被缓存,因此 x 和 y 实际上引用的是同一个对象

  • 基本数据类型 == 包装类:自动拆箱后比较值

  • 自动拆箱可能导致 NullPointerException:如果包装类对象为 null,拆箱时会抛出异常

    int num1 = 10;
    int num2 = 10;
    Integer obj1 = 10;
    Integer obj2 = new Integer(10);
    
    System.out.println(num1 == num2); // true,值相等
    System.out.println(obj1 == obj2); // false,引用不同
    System.out.println(num1 == obj1); // true,自动拆箱后比较值
    
    Integer obj = null;
    int num = obj; // 抛出 NullPointerException
    

equal()方法

equal方法是Object类中的方法,只能使用引用类型进行调用

在 Object 类中,equals() 方法的默认实现是比较两个对象的引用是否相同(即 == 比较)

默认的 equals() 方法通常不能满足实际需求,因此大多数类(如 String、Integer 等)都会重写 equals() 方法,以比较对象的内容是否相等

重写规则:

  • 自反性:x.equals(x) 必须为 true

  • 对称性:如果 x.equals(y) 为 true,则 y.equals(x) 也必须为 true

  • 传递性:如果 x.equals(y) 为 true,且 y.equals(z) 为 true,则 x.equals(z) 也必须为 true

  • 一致性:如果对象没有修改,则多次调用 x.equals(y) 的结果应该一致

  • 非空性:x.equals(null) 必须为 false

    class Person {
        String name;
        int age;
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj) return true; // 自反性
            if (obj == null || getClass() != obj.getClass()) return false; // 非空性和类型检查
            if(obj instanceof Person){
                Person person = (Person) obj; // 类型转换
            return age == person.age && name.equals(person.name); // 比较内容
            }
            
        }
    }
    
equal一些知识点
集合框架:HashSet、HashMap 等集合类依赖 equals() 方法来判断元素是否相等
如果重写了 equals() 方法,通常也需要重写 hashCode() 方法
根据 Java 规范,若 a.equals(b) 为 true,则 a.hashCode() 必须等于 b.hashCode() ,否则在集合类(如 HashMap)中会出现逻辑错误
使用 Objects.hash(field1, field2) 生成哈希值

toString方法

toString() 是 Java 中 Object 类的基础方法,所有类默认继承该方法,用于将对象转换为字符串表示形式

当对象被直接传递给 System.out.println() 、字符串拼接或日志输出时,toString() 会被自动调用

默认返回值:类名 + @ + 十六进制哈希码(如 Person@15db9742)

hashCode方法

hashCode() 是 Object 类提供的 原生方法(native),用于将对象的内容或存储信息映射为一个 整数(哈希码)。其默认实现可能与对象内存地址相关,但具体逻辑由 JVM 决定

在 Object 类中,hashCode() 方法的默认实现是返回对象的内存地址的哈希值

作用与原则

  1. 散列集合优化:在 HashSet、HashMap 等散列存储结构中,hashCode 用于快速定位对象存储位置,减少 equals 方法的调用次数
  2. 唯一性标识:不同对象的哈希码可能相同(哈希冲突),但相同对象的哈希码必须一致
  3. 等价性规则:若 obj1.equals(obj2) == true,则 obj1.hashCode() == obj2.hashCode() 必须成立,反之不一定成立
  4. 非等价性补充:若两个对象哈希码不同,则它们一定不相等
  5. 避免可变字段:参与哈希码计算的字段应为不可变类型,防止哈希码变化导致集合操作异常。哈希码在对象生命周期内应保持稳定(不可变对象最佳),否则会导致集合操作异常
  6. 覆盖字段一致性:哈希码计算需包含 equals 方法中对比的所有字段
  7. 均匀分布原则:设计哈希算法时,应尽量使不同对象生成的哈希码均匀分布
  8. 对象状态变更:若对象存入集合后修改参与哈希码计算的字段,可能导致无法检索
posted @ 2025-03-03 21:54  QAQ001  阅读(9)  评论(0)    收藏  举报