java中的Object类详解

 一、equals方法

== 是一个比较运算符

equals和==的区别(面试)

1、== :既可以判断基本类型,又可以判断引用类型是否相等

2、== :判断基本类型,判断的是是否相等

3、== :判断引用类型,判断的是地址是否相等,即判断是否为同一个对象

4、equals 是Object类方法,只能判断引用类型是否相等

5、默认(子类未重写equals方法时)判断的是地址是否相等,子类(Object的子类)中往往重写该方法,用于判断内容是否相等,比如integer\String

//Jdk源码,Object类的equals方法  就是默认比较对象地址是否相同
public boolean equals(Object obj){
    return (this == obj);
}

 String类的equals方法改写了Object类的equals方法,变成了判断两个值是否相等

//Jdk源码,Object类的 子类String类的equals方法
public boolean equals(Object anObject) {
    if (this == anObject) {//如果是同一个对象,则返回true
        return true;
    }
    if (anObject instanceof String) {//判断类型
        String anotherString = (String)anObject;//向下转型
        int n = value.length;
        if (n == anotherString.value.length) {//若长度相同
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {//然后一个一个的比较字符
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;//若两个字符串的每个字符都相等 返回 true
        }
    }
    return false;
}

二、练习

1、重写equals方法

package com.lmdedu.object;

public class EqualsExercise01 {
    public static void main(String[] args) {
        Person person1 = new Person("lmd",22,'男');
        Person person2 = new Person("lmd",22,'男');

        System.out.println("未重写equals之前");
        //输出f,因为此时还没有重写equals,用的是Object类的equals方法
        System.out.println(person1.equals(person2));

        System.out.println("重写equals之后");
        System.out.println(person1.equals(person2));//输出t
    }

}

class Person{
    private String name;
    private int age;
    private char 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;
    }

    //重写equals方法
    //要求比较两个Person对象的各个属性值 都一样
    public boolean equals(Object obj){
        //若比较的两个对象为同一个地址则直接返回true
        if(this == obj){
            return true;
        }
        //类型判断
        if(obj instanceof Person){//是Person类才进行比较
            //多态要向下转型后,才能获得子类的特有属性
            //进行向下转型,因为需要得到obj的各个属性,
            Person p = (Person) obj;
            //name为String,为引用数据类型,因为这里只是判断值是否相等,
            //而 ==运算符在判断引用数据类型时,判断的是地址是否相等,不能完成题目要求
            //String类的equals,在判断时,判断的是内容是否相等,所以采用 equals
            //age和gender属于基本数据类型,==在判断基本数据类型时,判断的是值是否相等,所以用==,
            //另外 equals也不能判断 基本数据类型
            return p.name.equals(this.getName()) && p.age == this.age && p.gender == this.gender;
        }
        return false;
    }
}
2、看看输出真假 

  1)判断p1 == p2 ,p1p2为引用数据类型, ==运算符在判断引用数据类型时,判断的是地址,所以为false

  2)判断p1.name.equals(p2.name) name为String类,String类的equals方法(重写过)为判断内容是否一样所以true

  3)判断p1.equals(p2) p1并未重写equals类,所以用的是Object类的equals方法,判断方法是this == obj,因为p1为引用数据类型,所以判断的是地址,所以false

  4)判断s1.equals(s2) s1、s2为String类,String类的equals方法(重写过)为判断内容是否一样所以true

  5)判断s1 == s2 ,String类为 引用数据类型,判断 地址,所以false

3、

 t t t f t 编译不通过

三、hashcode方法

对象.hashcode();

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

由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址(真正的对象地址)转换成一个整数来实现的,但是 Java 编程语言不需要这种实现技巧。)

四、toString方法

package com.lmdedu.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);
        //若没有重写toString,则用Object的toString源码
        System.out.println(monster.toString() + "hashcode=" + monster.hashCode());

        System.out.println("==当直接输出一个对象时,toString方法会被默认调用==");
        System.out.println(monster);//Monster{name='小妖怪', job='巡山', salary=1000.0}
    }
}

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

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

    //重写toString方法,输出对象的属性
    //使用快捷键即可
    @Override
    public String toString() {//重写后,一般就是将对象的属性输出
        return "Monster{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", salary=" + salary +
                '}';
    }
}

五、finalize方法(实际开发中,几乎不使用,面试可能问而已)

package com.lmdedu.object;

public class Finalize {
    public static void main(String[] args) {
        Car bmw = new Car("宝马");
        //将bmw与堆中的Car对象的指向 切断,bmw就变成了垃圾,垃圾回收器就会回收(销毁)对象
        //在销毁对象前,会调用该对象的finalize方法。
        //我们可以重写finalize方法,写自己的一些业务逻辑
        //若不重写finalize方法,那么就会调用Object类的finalize方法,即默认处理
        bmw = null;
        System.gc();//主动调用垃圾回收器
        System.out.println("程序退出");

    }
}

class Car{
    private  String name;

    public Car(String name) {
        this.name = name;
    }
    //快捷键生成

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值