您的位置:

Java Object类方法

Java中所有的类都是继承自Object类,因此Object类中的方法也是所有类可以使用的方法,本文将从以下角度对Java Object类方法进行详细阐述。

一、equals()方法

Object类中的equals()方法是用来判断两个对象是否相等的方法,其实现如下:

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

由于该方法只是简单地比较对象的地址是否相等,因此需要在自定义类中重写equals()方法,来判断两个对象的实际内容是否相等。

例如:

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

    //省略构造方法和其他方法
    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Person) {
            Person p = (Person) obj;
            return this.name.equals(p.name) && this.age == p.age;
        }
        return false;
    }
}

在该示例中,如果两个Person对象的name和age都相等,则认为这两个对象相等。这样就可以使用equals()方法判断两个Person对象是否相等了。

二、hashCode()方法

hashCode()方法返回对象的哈希码,哈希码是一个int类型的数值。

Object类中的hashCode()方法实现如下:

public native int hashCode();

很显然,该方法返回的哈希码仅仅是对象的地址在内存中的位置。

在自定义类中需要重写hashCode()方法来获得合适的哈希码,一般使用对象的属性计算哈希码,如下所示:

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

    //省略构造方法和其他方法
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

在该示例中,使用Objects类的hash()方法来计算哈希码,该方法中可以传入多个属性,每个属性的哈希码都会参与计算,得出最终哈希码。

三、toString()方法

toString()方法返回对象的字符串表达形式,一般在输出对象时使用。Object类中的toString()方法实现如下:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

该实现方式可读性不高,因此在自定义类中一般需要重写toString()

例如:

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

    //省略构造方法和其他方法
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

在该示例中,toString()方法返回了Person对象的属性信息,方便在输出时查看对象的实际信息。

四、getClass()方法

getClass()方法返回对象所属的类的Class对象,该对象包含了该类的一些信息,如类名、方法等。

例如:

    public static void main(String[] args) {
        Person person = new Person();
        Class clazz = person.getClass();
        System.out.println(clazz.getName()); //输出Person类的类名
    }

五、wait()、notify()、notifyAll()方法

这三个方法都是用来实现线程之间的通信的,使用时需要在synchronized关键字的保护下进行,每个方法的作用如下:

  • wait()方法:将当前线程置于等待状态,并释放锁
  • notify()方法:唤醒一个正在等待该对象的线程
  • notifyAll()方法:唤醒所有正在等待该对象的线程

例如:

public class MyRunnable implements Runnable {
    private Object obj;
    public MyRunnable(Object obj) {
        this.obj = obj;
    }

    @Override
    public void run() {
        synchronized (obj) {
            try {
                System.out.println("线程" + Thread.currentThread().getName() + "开始等待...");
                obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程" + Thread.currentThread().getName() + "被唤醒了!");
        }
    }
}

public static void main(String[] args) {
    Object obj = new Object();
    Thread t1 = new Thread(new MyRunnable(obj), "t1");
    Thread t2 = new Thread(new MyRunnable(obj), "t2");
    Thread t3 = new Thread(new MyRunnable(obj), "t3");

    //启动三个线程
    t1.start();
    t2.start();
    t3.start();

    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    synchronized (obj) {
        obj.notify();
        //obj.notifyAll(); //唤醒所有线程
    }
}

该示例中,三个线程分别对同一个对象进行了wait()操作,主线程在等待1s后唤醒一个线程。运行结果如下:

线程t2开始等待...
线程t1开始等待...
线程t3开始等待...
线程t1被唤醒了!

六、clone()方法

clone()方法是用来创建一个对象的副本的方法。在自定义类中需要重写clone()方法,并实现Cloneable接口,如下所示:

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

    //省略构造方法和其他方法
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

在该示例中,由于Object类中的clone()方法是protected类型的,因此需要在子类中实现一份public类型的clone()方法来进行克隆操作。使用时需要注意,在对象克隆完成后,克隆对象和原对象共享对象引用,因此需要进行深拷贝(也就是复制对象的内容而不是引用)操作。

七、finalize()方法

finalize()方法是Java在对象被垃圾回收前进行一些必要的清理工作的方法。一般不建议使用,因为垃圾回收是不确定时间的,可能并不会进行回收操作。

示例中不再赘述,此处略去。