Java基础10

gjwqz / 2024-08-27 / 原文

Object类

类java.lang.Object是类层次结构的根类,即所有其它类的父类。每个类都使用Object作为超类

 注意:

> Object类中声明的结构(属性、方法等)就具有通用性。

  > Object类中没有声明属性

  > Object类提供了一个空参的构造器

  > 重点关注: Object类中声明的方法

常用方法

重点方法: equals() \ toString()

了解方法: clone() \ finalize()

后续了解的方法:getClass() \ hashCode() \ notify() \ notifyAll() \ wait() \ wait(xx) \ wait(xx,yy)

clone()

clone()方法是用来创建并返回此对象的一个副本的。换句话说,它可以帮助我们复制一个对象。

前提:只有实现了Cloneable接口的类才能被复制,否则调用clone()方法时会抛出CloneNotSupportedException异常

// 定义一个实现了Cloneable接口的类
class MyClass implements Cloneable {
    int value;

    public MyClass(int value) {
        this.value = value;
    }

    // 重写Object类的clone()方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "MyClass{" + "value=" + value + '}';
    }
}

public class Main {
    public static void main(String[] args) {
        try {
            MyClass obj1 = new MyClass(10);
            MyClass obj2 = (MyClass) obj1.clone(); // 复制对象
            System.out.println("obj1: " + obj1); // 输出:obj1: MyClass{value=10}
            System.out.println("obj2: " + obj2); // 输出:obj2: MyClass{value=10}
            System.out.println("obj1 == obj2: " + (obj1 == obj2)); // 输出:obj1 == obj2: false,说明两个对象在内存中的地址不同
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

定义了一个实现了Cloneable接口的类MyClass,并重写了clone()方法。

在main方法中,我们创建了一个MyClass对象obj1,并使用clone()方法复制了obj1得到了obj2。通过输出我们可以看到,obj1和obj2的值是一样的,但是它们在内存中的地址是不同的,说明它们是两个不同的对象。

finalize()

 当垃圾回收器确定不存在对该对象的更多引用时,对象的垃圾回收器将调用此方法

注意:finalize()方法并不能保证一定会被执行,也不能保证何时被执行。因此,我们不能依赖finalize()方法来执行一些重要的清理工作,比如关闭文件、断开网络连接等

class MyClass {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("MyClass对象被垃圾回收器回收了");
        super.finalize(); // 调用父类的finalize()方法
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj = null; // 将obj引用置为null,使得原来的MyClass对象可以被垃圾回收器回收
        // 在这里,我们并不能确定MyClass对象的finalize()方法是否已经被执行,因为垃圾回收器的行为是不可预测的
    }
}

定义了一个类MyClass,并重写了finalize()方法。在main方法中,我们创建了一个MyClass对象obj,然后立即将obj引用置为null,使得原来的MyClass对象可以被垃圾回收器回收。但是,我们不能确定MyClass对象的finalize()方法是否已经被执行,因为垃圾回收器的行为是不可预测的。

equals()

java.lang.Object类中equals()的定义:

public boolean equals(Object obj){
    return (this == obj);
}

说明

 > 自定义的类在没有重写Object中的equals()方法的情况下,调用的就是Object类中声明的equals(),比较两个对象的引用地址是否相同。(或比较两个对象是否指向了堆空间中的同一个对象实体

> 对于像String、File、Data和包装类等,它们都重写了Object类中的equals()方法,用于比较两个对象的实体内容是否相等。

package com.atgjwqz.exercise;

public class UserTest {
    public static void main(String[] args) {
        User u1 = new User("Tom", 12);
        User u2 = new User("Tom",12);
        System.out.println(u1.equals(u2)); //输出:false  判断的是地址值

        String str1 = new String("hello");
        String str2 = new String("hello");
        System.out.println(str1 == str2);// false
        System.out.println(str1.equals(str2)); //true


    }
}
class User{
    String name;
    int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

开发中的使用说明

> 实际开发中,针对于自定义的类,常常会判断两个对象是否equals(),而此时主要是判断两个对象的属性值是都相等,所以要重写Object类的equals()方法。

> 如何重写: ① 手动自己实现  ② 调用IDEA自动实现(推荐)

区分== 和 equals()

==:运算符

① 适用范围: 基本数据类型、引用数据类型

② 基本数据类型:判断数据值是否相等

char c1 = 'A';
int i1 = 65;
sout(c1 == i1);  //true  c1的类型会自动提升为int然后比较
float f1 = 12.0F;
int i2 = 12;
sout(f1 == i2);   //true  int类型自动提升为float

   引用数据类型变量:比较两个引用变量的地址值是否相等。(或比较两个引用是否指向同一个对象实体)

equals():方法

> 使用范围:只能使用在引用数据类型上。

> 具体使用:对于类来说,重写equals()和不重写equals()的区别。

案例:

编写Order类,有int型的orderId,String型的orderName,相应的getter()和setter()方法,两个参数的构造器。

重写父类的equals()方法:public boolean equals(Object obj),并判断测试类中创建的两个对象是否相等

public class Order {
    int orderId;
    String orderName;

    public Order(int orderId, String orderName) {
        this.orderId = orderId;
        this.orderName = orderName;
    }

    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    @Override
    public boolean equals(Object obj) {
        if(this == obj){
            return true;
        }
        if (obj instanceof Order){
            Order order = (Order) obj;
            if(this.orderId == order.orderId && this.orderName == orderName) {
                return true;
            }
        }
        return false;
    }
}
public class OrderTest {
    public static void main(String[] args) {
        Order o1 = new Order(1001,"orderAA");
        Order o2 = new Order(1001,"orderAA");
        System.out.println(o1.equals(o2));  //true
    }
}