第四节Object祖类

第十三章Object祖类

java.lang.Object类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类都可以使用。在对象实例化的时候,最终找的父类就是Object。

在Object类中有一段描述

Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.

大致意思就是:
类对象是类层次结构的根。每个类都有Object作为超类。所有对象(包括数组)都实现此类的方法。

方法名介绍
public String toString()返回该对象的字符串表示。
boolean equals(Object obj)指示其他某个对象是否与此对象“相等”
public native int hashCode()对象的内存地址
finalize()垃圾回收之前执行的代码

接下来对Object这个祖类中的方法进行讲解

1.toString方法

1.1方法摘要

方法名介绍
public String toString()返回该对象的字符串表示。我们在输出对象时,默认会调用该对象的toString()方法;

toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。

举例:

public class ToStringDemo {
    public static void main(String[] args) {
        Person person=new Person(21,"张三");
        System.out.println(person);

    }

}

class Person{
    private int age;
    private String name;

    public Person() {
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

输出结果:

toString.Person@4eec7777
包名@内存地址    

1.2.2 覆盖重写

如果不希望使用toString方法的默认行为,则可以对它进行覆盖重写。

public class ToStringDemo {
    public static void main(String[] args) {
        Person person=new Person(21,"张三");
        System.out.println(person);

    }

}

class Person{
    private int age;
    private String name;

    public Person() {
    }

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

测试结果:

Person{age=21, name='张三'}

重写的规则 自己说了算

上方toString方法就是idea快捷生成的 alt+insert 选择toString即可

2.equals方法

2.1 方法摘要

方法名作用
public boolean equals(Object obj)指示其他某个对象是否与此对象“相等”。

调用成员方法equals并指定参数为另一个对象,则可以判断这两个对象是否是相同的。这里的“相同”有默认和自定义两种方式。

2.2 默认地址比较

如果没有覆盖重写equals方法,那么Object类中默认进行==运算符的对象地址比较,只要不是同一个对象,结果必然为false。

源码:

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

我们知道,引用存储的是对象的内存地址。所以这里比较的就是两个引用的内存地址

2.3对象内容比较

public class equalsTest01 {
    public static void main(String[] args) {
		MyTime m1=new Mytime(2000,2,18);
		MyTime m2=new Mytime(2000,2,18);
        System.out.println(m1.equals(m2));//true
    }
}

class MyTime {
    int year;
    int month;
    int day;

    public Mytime() {
    }

    public Mytime(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }


    /*
    public boolean equals(Object obj){
        //如果obj是空就返回null
        if (obj==null){
            return false;
        }
        //如果obj不是Mytime 就返回false
        if (!(obj instanceof  Mytime)){
            return false;
        }
        //如果obj和this保存的内存地址相等,没必要比较了,直接返回true
        //内存相等的情况下,堆内存的对象肯定是同一个
        if(this==obj){
            return true;
        }
        //程序到此处说明了什么
        //说明obj不是null obj是mmm类型
        Mytime t=(Mytime) obj;
        if (this.year==t.year &&this.month==t.month&&this.day==t.day){
            return true;
        }
        //程序能到这里返回false
        return false;
    }
    */

    //直接生成的 alt+insert
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Mytime mytime = (Mytime) o;
        return year == mytime.year && month == mytime.month && day == mytime.day;
    }

    @Override
    public String toString() {
        return "Mytime{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
}

注意:只要不是基本数据类型我们就要用equals来比较

3.hashCode()方法

代码示例:

/*
hashCode方法:
        在Object中的hashCode方法是怎样的?
public native int hashCode();
        这个方法不是抽象的,带有native关键字,底层调用c++程序
        hashCode()返回的是哈希码
        实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值
        所以hashCode()方法的执行结果可以等同看作一个java对象的内存地址
*/
public class hashCodeTest {
    public static void main(String[] args) {
        Object o=new Object();
        int hashCodeValue=o.hashCode();
        System.out.println(hashCodeValue);
    }
}

4.finalize()方法

代码示例:

/*
非重点
关于Object类中的finalize()方法
    1.在Object类中的源代码是什么?
         protected void finalize() throws Throwable { }
         GC来负责调用finalize()方法。
    2.finalize()方法只有一个方法体,里面没有代码,而且这个方法是protected修饰的
    3.这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法。
    4.finalize()方法执行的时机
        当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法
    5.finalize()方法实际上是sun公司为java程序员准备的一个时机,垃圾销毁时机。
    如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法中
    6.java中的垃圾回收器不是轻易启动的,垃圾太少,或者时间不到,种种条件下

 */
public class finalizeTest01 {
    public static void main(String[] args) {
        Person p=new Person();
        //怎么把person对象变为垃圾
        p=null;
        //有一段代码是建议垃圾回收器启动
        System.gc();//建议启动!!! 不一定启动
    }
}
//业务需求:所有对象在JVM中被释放的时候,请记录一下时间
//记录对象被释放的时间点,这个负责记录的代码放在那里?finalize()
class Person{
    //重写finalize()方法
    //person类型的对象被垃圾回收器回收的时候,垃圾回收器负责调用p.finalize();
    protected void finalize() throws Throwable {
        System.out.println("即将被销毁");
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值