目录

  • Object类详解
  • 一、==和equals的对比
  • 1.1 ==是一个比较运算符
  • 1.2 equals方法
  • 二、hashCode方法
  • 三、toString方法
  • 四、finalize方法

Object类详解

一、==和equals的对比

1.1 ==是一个比较运算符

  1. ==:即可以判断基本类型,又可以判断引用类型
  2. ==:如果判断基本类型,判断的是值是否相等
  • 例如:int i = 10;double d = 10.0
  1. ==:如果判断应用类型,判断的是地址是否相等,即判断是否是一个对象

1.2 equals方法

  1. equals:是Object类中的方法,只能判断引用类型

重写equals方法

题目:判断两个 Person 对象的内容是否相等,如果两个 Person 对象的各个属性值都一样,则返回 true,反之 false

package com.hspedu.object_;

import java.util.Objects;

public class EqualsExercise {
    public static void main(String[] args) {
        Person person1 = new Person("jack", 10, '男');
        Person person2 = new Person("jack", 10, '男');

        System.out.println(person1.equals(person2));//false
    }
}

class Person {//extends object 中的equals
    private String name;
    private int age;
    private char gender;

    //重写equals方法


    @Override
    public boolean equals(Object o) {
        //如果比较的对象是同一个对象,则直接返回true
        if (this == o) {
            return true;
        }
       /* 自己写的
       else if (o == null) {
            return false;
        } else if (o instanceof Person) {
            Person p = (Person) o;
            return p.getAge() == this.age && p.getName().equals(this.name)
                    && p.getGender() == this.gender;
        }else {
            return false;
        }*/

        //老师的思路
        if (o instanceof Person) {
            Person p = (Person) o;
            return p.getAge() == this.age && p.getName().equals(this.name)
                    && p.getGender() == this.gender;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, gender);
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }
}

二、hashCode方法

功能:返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。

  1. 提供具有哈希结构的容器效率!
  2. 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
  3. 两个引用,如果指向的是不同对象,则哈希值不一样的
  4. 哈希值主要根据地址来计算的,但不能将其等价为地址
package com.hspedu.object_;

public class HashCode_ {
    public static void main(String[] args) {
        AA obj1 = new AA();
        AA obj2 = new AA();
        AA obj3 = obj1;
        System.out.println("obj1.hashCode()="+obj1.hashCode());
        System.out.println("obj2.hashCode()="+obj2.hashCode());
        System.out.println("obj3.hashCode()="+obj3.hashCode());
    }
}

class AA{

}

5.后面在集合中,hashCode 如果需要,则会重写

三、toString方法

功能:全类名(包名+类名)+@+哈希值的十六进制

  • 重写 toString 方法,打印对象或拼接对象时,都会自动调用该对象的 toString 形式
  • 当直接输出一个对象时,toString 方法会被默认调用
  • 比如:System.out.println(monster);

一般会用重写之后的toString方法会打印类名和其属性

package com.hspedu.object_;

public class ToString {
    public static void main(String[] args) {
      /*
         Object 的toString() 源码
         (1) getClass().getName() 全类名(包名+类名)
         (2) Integer.toHexString(hashCode()) 将对象的hashCode值转成16进制字符串
         public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
         }
        }*/

        Monster monster = new Monster("小妖怪", "巡山", 1000);
        System.out.println(monster.toString() +  " hashcode=" +monster.hashCode());
        //com.hspedu.object_.Monster@49e4cb85
        System.out.println("==当直接输出一个对象时,toString 方法会被默认调用==");
        System.out.println(monster);
    }
}

class Monster{
    private String name;
    private String job;
    private double sal;

    //重写toString方法,输出对象的属性
    //使用快捷键 alt+inset -> toString

    @Override
    public String toString() {//重写后,一般是把对象的属性输出,当然程序员也可以自己定制
        return "Monster{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                '}';
    }

    public Monster(String name, String job, double sal) {
        this.name = name;
        this.job = job;
        this.sal = sal;
    }

    public String getName() {
        return name;
    }

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

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }
}


四、finalize方法

  1. 当对象被回收时,系统自动调用该对象的 finalize 方法。子类可以重写该方法,做一些释放资源的操作
  2. 什么时候被回收: 当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来 销毁该对象,在销毁该对象前,会先调用 finalize 方法
  3. 垃圾回收机制的调用,是由系统来决定(即有自己的 GC 算法), 也可以通过 System.gc() 主动触发垃圾回收机制,测 试:Car [name
  • 我们在实际开发中,几乎不会运用 finalize , 所以更多就是为了应试
package com.hspedu.object_;


//演示 Finalize的用法
public class Finalize_ {
    public static void main(String[] args) {
        Car car = new Car("宝马");

        //这时 car对象就是个垃圾,垃圾回收器就会回收(销毁)对象,在销毁对象前
        //,会调用该对象的finalize方法
        //程序员就可以在 finalize中,写自己的业务逻辑(比如释放资源:数据库连接,或者打开文件..)
        //,如果不重写finalize,那么就会调用Object类的 finalize,即默认处理
        //,如果重写了finalize,就可以实现自己的逻辑
        car = null;
        System.gc();
        System.out.println("程序退出了....");
    }
}

class Car{
    private String name;

    @Override
    protected void finalize() throws Throwable {
        System.out.println("我们销毁 汽车" + name);
        System.out.println("释放了某些资源...");
    }

    public Car(String name) {
        this.name = name;
    }

}