Java中的Object类的理解及其方法内容的详细讲解

前言

一、Object类

1.什么是Object类 ?

    Object类是所有类的最终父类,就算某一个类的父类没有声明为Object那它的最终的祖先肯定是Object。
    Object类源码就在所下载的jdk的包下面,有src压缩包,里面有Object类的源码,就在oracle网站下载的API的当中 java.lang这个包下面,里面有很多定义好的方法:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后就得到了Object类的源码,里面有一段英文的文档注释:
在这里插入图片描述
就相当于是API里面的文档注释,就是类似是说明书,就是直接翻译过来的:
在这里插入图片描述
具体的方法如下:
在这里插入图片描述

2.具体方法的详细讲解

(1) getClass()

public final native Class<?> getClass();
//相当于获取对象最本质的数据类型

我们可以根据实例来理解:

public class ObjectDemo {
    public static void main(String[] args) {
        String s = "abc";
        System.out.println(s.getClass());
        //多态
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        System.out.println(a1.getClass());
        System.out.println(a2.getClass());
    }
}
//多态
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}
验证s,a1,a2对象所调用的类:
![在这里插入图片描述](https://img-blog.csdnimg.cn/57e64bb19a304be787d967928d0a73bd.png)2hashCode()

```java
public native int hashCode();
//返回对象的哈希码的值,如果该类没有重写hashCode的
//hashCode默认值就是对象在堆内存中的真实物理地址

    我们可以根据实例来理解(在没有重写方法前,调用的是Object类里面的hascode()的方法,默认值就是对象在堆内存中的真实物理地址):

public class ObjectDemo {
    public static void main(String[] args) {
        //多态
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        System.out.println(a1.hashCode());
        System.out.println(a2.hashCode());
    }
}
//多态
class Animal {}
class Dog extends Animal {}
class Cat extends Animal {}

结果:显示的是a1和a2的真实物理地址
在这里插入图片描述
若对hascode()方法进行重写就会返回重写的值,直接覆盖了默认值:

public class ObjectDemo {
    public static void main(String[] args) {
        //多态
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        System.out.println(a1.hashCode());
        System.out.println(a2.hashCode());
    }
}
//多态
class Animal {
//重写了hascode()方法
    @Override
    public int hashCode() {
        return 100;
    }
}
class Dog extends Animal {}
class Cat extends Animal {}

结果:显示的是a1和a2的重写后的值
在这里插入图片描述
(3)equals(Object obj)


public boolean equals(Object obj) {
    return (this == obj);
}
//Object本身equals比的是自身对象this和传入对象obj的地址值
//如需重新定义等于,则子类重写,按需比较即可

    注意这里的equals方法里面返回的是this==obj,也就是说如果传入的不是自己本身,就永远是返回false,注意这里的 两边永远比的是对象的真实物理内存地址!

public class ObjectDemo {
    public static void main(String[] args) {
        //多态
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        System.out.println(a1.hashCode());
        System.out.println(a2.hashCode());
        System.out.println(a1 == a2);
        //== 两边永远比的是对象的真实物理内存地址!
        System.out.println(a1.equals(a2));
    }
}
//多态
class Animal {}
class Dog extends Animal {}

结果:a1与a2的真实物理地址不同,返回的是false,equals()方法没有传入自己也是返回false:
在这里插入图片描述
如果对equals(Object obj)方法进行重写,就会改变结果,根据自己所需要比较的内容来比是否相等:

public class ObjectDemo {
    public static void main(String[] args) {
        Person p1 = new Person("小明",21);
        Person p2 = new Person("小明",21);
        System.out.println(p1);
        System.out.println(p2);
        System.out.println(p1.equals(p2));
    }
}
class Person {
    String name;
    int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    //重写equals(Object obj)方法
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() == obj.getClass()) {
            Person other = (Person) obj;
            return this.name.equals(other.name) && this.age == other.age;
        } else {
            return false;
        }
    }
}

结果:重写后的equals(Object obj)方法,会根据所写的要求来执行,不会默认执行比较真实物理地址的值:
在这里插入图片描述

(4)toString()

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
//Object本身的toString返回的是对象最本质的数据类型的名称+"@"+哈希值的十六进制形式
//如需重新定义对象的字符串形式,则子类重写,按需拼接数据即可

注意,打印对象本身就是相当于打印它们的toString()方法;

public class ObjectDemo {
    public static void main(String[] args) {
        //多态
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        System.out.println(a1.hashCode());
        System.out.println(a2.hashCode());
        System.out.println(a1);
        System.out.println(a2);
        System.out.println(a1 == a2);
        //无论hashCode是否重写 == 两边永远比的是对象的真实物理内存地址!
        System.out.println(a1.equals(a2));
    }
}
//多态
class Animal {
    @Override
    public int hashCode() {
        return 100;
    }
}
class Dog extends Animal {}
class Cat extends Animal {}

结果,打印a1和a2,就是相当于打印它们的toString()方法,hashCode重写,100的十六进制是64
在这里插入图片描述
如果重写toString()方法,会根据自己所需所写,改变了原本的打印方式:

public class ObjectDemo {
    public static void main(String[] args) {
        Person p1 = new Person("小明",21);
        Person p2 = new Person("小李",11);
        System.out.println(p1);
        System.out.println(p2);
    }
}
class Person {
    String name;
    int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //重写toString()方法
    @Override
    public String toString() {
        return name + ":" + age;
    }
}

结果:将toString()方法改写成只打印名字和年龄
在这里插入图片描述
(5)clone()

protected native Object clone()
//对象的拷贝,对于任何对象 x

    创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。这样做的目的是,对于任何对象 x:

  • 表达式: x.clone() != x为 true。【保证肯定有新对象创建】
  • 表达式: x.clone().getClass() == x.getClass()也为 true,但这些并非必须要满足的要求。【保证对象和副本之间的数据类型是一致的】
  • 一般情况下: x.clone().equals(x)为 true,但这并非必须要满足的要求。 【保证对象和副本之间的数据内容是一致的】

    因为clone()方法的权限是protected,当不在一个包下且不在一个类下面是无法访问到的,必须得重写clone()的方法,也要实现接口 Cloneable,得让此类有接口 Cloneable的功能可以进行复制的方法。

    Object 类的 clone 方法执行特定的复制操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。注意,所有的数组都被视为实现接口 Cloneable。否则,此方法会创建此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我复制。所以,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。

Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。

返回: 此实例的一个副本。

抛出: CloneNotSupportedException - 如果对象的类不支持 Cloneable 接口,则重写 clone方法的子类也会抛出此异常,以指示无法复制某个实例。

public class ObjectDemo {
    public static void main(String[] args) {
        Person p3 = new Person("小刘",30);
        Person p4 = null;
        try {
            p4 = (Person) p3.clone();//p3的副本
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(p3);
        System.out.println(p4);
        System.out.println(p3 == p4);//p3和p4确实是两个对象
        System.out.println(p3.equals(p4));//p3和p4确实内容相等
        p3.name = "刘小刚";
        p3.age = 10;
        System.out.println(p3);
    }
}
class Person implements Cloneable{
    String name;
    int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //重写clone()方法
    @Override
    //要将权限protected改成public
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    //重写toString()方法
    @Override
    public String toString() {
        return name + ":" + age;
    }

    //重写equals(Object obj)方法
    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() == obj.getClass()) {
            Person other = (Person) obj;
            return this.name.equals(other.name) && this.age == other.age;
        } else {
            return false;
        }
    }
}

    结果:p4就是p3拷贝的一个新对象,p3的一个副本,内容一致,但是真实物理地址不一致,p3改变了内容,p4也不会改变,两个是两个对象,p4只是原p3的一个拷贝。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值