JAVA----Object类

本文深入探讨Java中Object类的功能和用途,包括构造器、clone方法的实现与注意事项、equals方法的重写规则、finalize方法的作用及其它常用方法的介绍。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java.lang.Object是JAVA中所有类层次结构的根,所有的对象包括数组都实现了Object类的方法。


构造器:

public Object()

方法:

1. clone()

该方法需要实现Cloneable接口,重写clone方法才能使用;
该方法会返回一个一摸一样的对象,但是该对象不等同于原来的对象
x.clone() != x;
例如:

class Person implements Cloneable{
    public String name;
    public int age;
    public Person(String name,int age ) {
        this.age = age;
    }
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}
public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("小明",18);
        Person p2 =  p1.clone();
        Person p3 = p1;
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p1==p2);
        System.out.println(p1==p3); 
    }
}

输出:
//后面的只是人为加的注解

366712642    //p1的hashCode
1829164700   //p2的hashCode
false        //p1==p2
true         //p1==p3

该方法是完全克隆了一个对象,并不仅仅是创建一个引用指向原来的对象。
但是需要注意,如果一个对象里面的属性包含引用的话,那么该引用属性也要实现Cloneable接口,因为引用在内存中存储的只是引用对象的hash值,克隆也只是克隆了hash值而已。

例如:

class Body{
    public int BODYNUM = 4;
}
class Person implements Cloneable{
    public String name;
    public int age;
    public Body body;       //body属性
    public Person(String name,int age,Body body ) {
        this.name = name;
        this.age = age;
        this.body = body;
    }
    public Person clone() throws CloneNotSupportedException {
        return (Person) super.clone();
    }
}
public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("小明",18,new Body());
        Person p2 =  p1.clone();
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.body==p2.body);
        p1.body.BODYNUM = 5;
        System.out.println(p2.body.BODYNUM);    
    }
}

输出:

366712642
1829164700
false          //p1==p2
true          //p1.body==p2.body
5            //p2的body属性的一个值

可以看到,修改了p1的body属性,p2的 body属性也修改了。那么就说明了,其实p1的body跟p2的body实质上还是同一个,因为克隆的只是引用值而已,引用还是指向内存中同一个区域。
这个时候,Body属性必须也实现Cloneable接口
例如:

class Body implements Cloneable{
    public int BODYNUM = 4;
    public Body clone() throws CloneNotSupportedException {
        return (Body) super.clone();
    }
}
class Person implements Cloneable{
    public String name;
    public int age;
    public Body body;
    public Person(String name,int age,Body body ) {
        this.name = name;
        this.age = age;
        this.body = body;
    }
    public Person clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone();
        person.body = body.clone();   //可以认为将包含引用的属性都要自己拷贝一遍
        return person;
    }
}
public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person("小明",18,new Body());
        Person p2 =  p1.clone();
        System.out.println(p1.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p1==p2);
        System.out.println(p1.body==p2.body);
        p1.body.BODYNUM = 5;
        System.out.println(p2.body.BODYNUM);    
    }
}

输出:

366712642
1829164700
false
false       //p1的body与p2的body不一样了
4          //修改p1的body后,p2并未受到修改

这也就是传说中的深拷贝,即在重写clone方法中拷贝所有的引用属性;

2. equals(Object obj)

该方法具有如下特性:

  • 自反性:对于任何非空引用x; x.equals(x)应当返回true;
  • 对称性:对于任何非空引用x,y;x.equals(y)返回true当且仅当y.equals(x)返回true;
  • 传递性:对于任何非空引用 x,y,z,如果x.equals(y)=true,y.equals.(z)=true,那么x.equals(z)=true
  • 一致性:对于任何非空引用 x,y,调用多次x.equals(y)返回结果应该相同;
  • 对于任何非空引用x,xequals(null)应该返回false;

源码如下:

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

很多都会重写该方法。

3. finalize()

是终止函数,JVM在进行垃圾回收的时候首先会调用这个函数,当某个对象被确认为无用信息的时候,那么就会释放该对象的内存,但是不一定有效。
一般人为不使用该方法。

class Person{
    //重写了Object类的finalize方法,当Person类被回收的时候首先调用该方法
    public void finalize() throws Throwable{ 
        System.out.println("回收前调用");
    }
}
public class Run {
    public static void main(String[] args) {
        Person p = new Person();
        p = null;
        System.gc();
    }   
}

输出:

回收前调用

表明gc的时候调用了Person类的finalize方法
但是需要注意,只有p没有指向的时候,即被认为是无用信息的时候才会被回收,如果去掉上面的p=null,那么还是不会有输出。

4. getClass()

返回该对象运行时的类。
例如:

public class Run{
    public static void main(String[] args) throws CloneNotSupportedException {
        String a = "a";
        System.out.println(a.getClass());

    }
}

输出:

class java.lang.String

5. hashCode()

该方法返回对象的hash值,具有如下特点:

  • 同一对象调用多次该方法应该返回相同值
  • 如果两个对象通过equals方法返回true,那么调用hashCode方法应该返回相同hash值
  • 不是一定要“两个对象通过equals方法返回true,那么调用hashCode方法应该返回相同hash值”,但是通常应该这么做,提高HashTable的性能

6. notify()

该方法唤醒在此同步监视器上等待的一个线程,如果有多个线程等待,则随机唤醒一个。

  • 如果在synchronized修饰的同步方法中使用,则可以直接使用该方法,因为this就是同步监视器
  • 如果在synchronized修饰的同步代码块中使用,则使用括号中的同步监视器来调用该方法。

7. notifyAll()

该方法唤醒在此同步监视器上等待的所有的线程。

8. toString()

该方法将任何对象转换为字符串类型
返回getClass().getName() + '@' + Integer.toHexString(hashCode())

例如:

public class Run {
    public static void main(String[] args) {
        Run r = new Run();
        System.out.println(r.toString());
        System.out.println(r.toString() instanceof String);
    }   
}

输出:

hello.Run@15db9742
true

9. wait()

该方法将当天线程进入等待,直到有其他线程唤醒它。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值