面向对象【Object类的方法】-LMLPHP

Java中Object类中的方法

Java中的Object类是所有类的根类,它包含一些在所有对象中通用的方法。这些方法在Java中的每个类中都是可用的,因为所有类都直接或间接地继承自Object类。

1.toString()方法

toString()方法是Object类中最常用的方法之一。它返回一个包含对象的字符串表示的文本。默认情况下,toString()方法返回一个由类名和对象的哈希码组成的字符串。在实际开发中,我们通常需要重写这个方法,以便根据对象的状态提供有意义的字符串表示

public class Person {
    private String name;
    private int age;

    // 构造方法、其他方法等

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + '}';
    }
}

// 使用toString()方法
Person person = new Person("John", 25);
System.out.println(person.toString()); // 输出: Person{name='John', age=25}

通过重写toString()方法,我们可以在打印对象时更容易地理解对象的内容。

2. equals()方法

equals()方法用于比较两个对象是否相等。默认情况下,它使用==运算符比较对象的引用地址。然而,通常我们需要在类中重写equals()方法,以便根据对象的内容进行比较。

public class Person {
    private String name;
    private int age;

    // 构造方法、其他方法等

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && Objects.equals(name, person.name);
    }
}

// 使用equals()方法
Person person1 = new Person("John", 25);
Person person2 = new Person("John", 25);
System.out.println(person1.equals(person2)); // 输出: true

重写了equals()方法以比较两个Person对象的内容。

3. clone()方法

clone()方法用于创建并返回对象的拷贝。在使用clone()方法时,被复制的类应该实现Cloneable接口,并且clone()方法应该被重写以提供正确的拷贝逻辑。

public class Person implements Cloneable {
    private String name;
    private int age;

    // 构造方法、其他方法等

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

// 使用clone()方法
Person person = new Person("John", 25);
Person clonedPerson = (Person) person.clone();

4. finalize()方法

当对象被回收时,系统自动调用该对象的 finalize() 方法。(不是垃圾回收器调用的,是本类对象调用的)
应该尽量避免使用finalize()方法,因为它的行为是不确定的,并且不保证会被及时调用

5. getClass()方法

获取对象的运行时类型

因为 Java 有多态现象,所以一个引用数据类型的变量的编译类型运行时类型可能不一致,因此如果需要查看这个变量实际指向的对象
的类型,需要用 getClass()方法

public static void main(String[] args) {
Object obj = new Person();
System.out.println(obj.getClass());//运行时类型
}

6. hashCode()方法

hashCode()方法返回对象的哈希码,通常用于散列算法和集合中。在使用集合框架时,重写hashCode()方法是与equals()方法一起确保正确性的良好实践。

public class Person {
    private String name;
    private int age;

    // 构造方法、其他方法等

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

// 使用hashCode()方法
Person person = new Person("John", 25);
System.out.println(person.hashCode());

7. notify()和notifyAll() 方法

这两个方法用于唤醒正在等待此对象监视器的线程。它们只能在同步代码块或同步方法中调用,并且只能被当前对象的持有者调用。

  • notify(): 唤醒在此对象监视器上等待的单个线程。如果有多个线程在等待,则唤醒其中任意一个线程。

  • notifyAll(): 唤醒在此对象监视器上等待的所有线程。

这两个方法需要注意以下几点:

  • notify()和notifyAll()方法只是唤醒线程,并不会立即释放锁,而是等到线程执行完临界区后才会释放锁。

  • 调用notify()和notifyAll()方法的线程必须拥有对象监视器的锁,否则会抛出IllegalMonitorStateException异常。

  • 被唤醒的线程依旧要竞争锁才能继续执行,即使被唤醒的线程优先级比当前线程高。

public class MyThread extends Thread {
    private final Object lock;

    public MyThread(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                System.out.println(Thread.currentThread().getName() + "线程进入等待状态");
                lock.wait();
                System.out.println(Thread.currentThread().getName() + "线程被唤醒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        MyThread thread1 = new MyThread(lock);
        MyThread thread2 = new MyThread(lock);
        MyThread thread3 = new MyThread(lock);

        thread1.start();
        thread2.start();
        thread3.start();

        Thread.sleep(1000); // 主线程睡眠1秒,确保子线程都进入等待状态

        synchronized (lock) {
            // 唤醒一个正在等待的线程
            // lock.notify();
            // 唤醒所有正在等待的线程
            lock.notifyAll();
        }
    }
}

8. wait()方法

wait()方法用于使当前线程进入等待状态,直到其他线程调用notify()或notifyAll()方法唤醒该线程。它必须在同步代码块或同步方法中调用,并且只能被当前对象的持有者调用。

wait(): 使当前线程等待,直到其他线程通过notify()或notifyAll()方法唤醒该线程。

  • wait(long timeout): 使当前线程等待一段指定的时间,直到其他线程通过
    notify()或notifyAll()方法唤醒该线程,或指定的时间到期。

  • wait(long timeout, int nanos): 使当前线程等待一段指定的时间,直到其他线程通过notify()或notifyAll()方法唤醒该线程,或指定的时间到期。

与notify()和notifyAll()方法一样,调用wait()方法的线程必须拥有对象监视器的锁,否则会抛出IllegalMonitorStateException异常。

public class MyThread extends Thread {
    private final Object lock;

    public MyThread(Object lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                System.out.println(Thread.currentThread().getName() + "线程进入等待状态");
                lock.wait();
                System.out.println(Thread.currentThread().getName() + "线程被唤醒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();
        MyThread thread = new MyThread(lock);

        thread.start();

        Thread.sleep(1000); // 主线程睡眠1秒,确保子线程进入等待状态

        synchronized (lock) {
            lock.notify();
        }
    }
}
 
03-15 04:45