文章目录
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();
}
}
}