【Java基础】第四章 Object 类应用

系列文章目录

[Java基础] 第一章 String类应用及分析
[Java基础] 第二章 数组应用及源码分析
[Java基础] 第三章 StringBuffer 和 StringBuilder 类应用及源码分析
[Java基础] 第四章 Object 类应用

在这里插入图片描述



前言

Java中的Object类是所有类的根类,它位于Java类层次结构的顶部。每个类都隐式地直接或间接地继承自Object类。Object类提供了一些通用的方法,可以在所有的Java对象中使用。
在这里插入图片描述


一、如何使用Object?

Object 类位于 java.lang 包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类。

Object 类可以显式继承,也可以隐式继承。

1.1、显式继承

public class Person extends Object{
    
    

}

1.2、隐式继承

public class Person{
    
    

}

1.3、Object类的构造函数

序号 构造方法 & 描述
1 Object()
构造一个新对象。

二、关于Object类的基本知识及应用

序号 方法 & 描述
1 protected Object clone()
创建并返回一个对象的拷贝
2 boolean equals(Object obj)
比较两个对象是否相等
3 protected void finalize()
当 GC (垃圾回收器)确定不存在对该对象的有更多引用时,由对象的垃圾回收器调用此方法。
4 Class getClass()
获取对象的运行时对象的类
5 int hashCode()
获取对象的 hash 值
6 void notify()
唤醒在该对象上等待的某个线程
7 void notifyAll()
唤醒在该对象上等待的所有线程
8 String toString()
返回对象的字符串表示形式
9 void wait()
让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
10 void wait(long timeout)
让当前线程处于等待(阻塞)状态,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过参数设置的timeout超时时间。
11 void wait(long timeout, int nanos)
与 wait(long timeout) 方法类似,多了一个 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。

由于所有类都直接或间接继承自Object类,因此Object类的方法可以在任何对象上使用。但是,需要注意的是,在重写Object类的方法时,应该按照特定的需求和语义来实现,以确保正确的行为。

2.1、toString()方法

该方法返回对象的字符串表示形式。默认情况下,它返回类名和对象的哈希码。通常,我们可以重写这个方法来返回我们自定义的字符串表示形式。

package com.kelvin.spiderx.test;

/***
 * @title ObjectTest
 * @desctption Object
 * @author kelvin
 * @create 2023/7/15 12:06
 **/
public class ObjectTest {
    
    

    public static void main(String[] args) {
    
    
        // 创建一个对象
        Person person = new Person("Kelvin", 25);

        // 调用toString()方法
        String str = person.toString();
        System.out.println("toString(): " + str);
    }
}

class Person {
    
    
    private String name;
    private int age;

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

结果:

toString(): com.kelvin.spiderx.test.Person@31f5fc51

2.1.1、溯源

通过Idea的快捷键(ctrl + 鼠标左键),选中【person.toString()】,会跳转到Person类的父类Obejct的toString方法。里面的重点是Object类里的Integer.toHexString(hashCode()) 以及 System类里的identityHashCode方法。
getClass().getName():获取当前类的名称
Integer.toHexString(hashCode()) :获取当前类在虚拟机里的身份地址哈希值的字符串信息

public class Object {
    
    
	public String toString() {
    
    
	    return getClass().getName() + "@" + Integer.toHexString(hashCode());
	}
	
	/**
	* See Also:
	equals(Object), System.identityHashCode
	**/
	public native int hashCode();
}

public final class System {
    
    
	public static native int identityHashCode(Object x);
}

2.1.2、重写toString方法,返回类里属性的值

class Person {
    
    
    private String name;
    private int age;

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
    
    
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

运行结果:

toString(): Person [name=Kelvin, age=25]

2.2、equals()方法

该方法用于比较两个对象是否相等。默认情况下,它比较对象的引用是否相等,即是否指向同一个对象。通常,我们需要根据对象的内容重写这个方法,以实现我们自己的相等逻辑。

package com.kelvin.spiderx.test;

/***
 * @title ObjectTest
 * @desctption Object
 * @author kelvin
 * @create 2023/7/15 12:06
 **/
public class ObjectTest {
    
    

    public static void main(String[] args) {
    
    
        // 创建一个对象
        Person person = new Person("Kelvin", 25);
        Person newPerson = new Person("Kelvin", 25); 

        // 调用equals()方法
        boolean isEqual = person.equals(newPerson);
        System.out.println("equals(): " + isEqual);
        System.out.println( System.identityHashCode(person) );
        System.out.println( System.identityHashCode(newPerson) );
    }
}

class Person {
    
    
    private String name;
    private int age;

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

结果:

equals(): false
366712642
1829164700

2.2.1、溯源

通过Idea的快捷键(ctrl + 鼠标左键),选中【person.equals】,会跳转到Person类的父类Obejct的equals方法。默认情况下,它比较对象的引用是否相等,即是否指向同一个对象(可以用System.identityHashCode方法来验证)。

public class Object {
    
    

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

public final class System {
    
    
	public static native int identityHashCode(Object x);
}

2.2.2、重写equals方法,比较类里属性的值是否相等

重写equals方法后,比较是否相同的类,以及类里属性的值是否相等


public class ObjectTest {
    
    

    public static void main(String[] args) {
    
    
        // 创建一个对象
        Person person = new Person("Kelvin", 25);
        Person newPerson = new Person("Kelvin", 25); 

        // 调用equals()方法
        boolean isEqual = person.equals(newPerson);
        System.out.println("equals(): " + isEqual); 
    }
}

class Person {
    
    
    private String name;
    private int age;

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object obj) {
    
    
        if (this == obj) {
    
    
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
    
    
            return false;
        }
        Person other = (Person) obj;
        return name.equals(other.name) && age == other.age;
    }
}

运行结果:

equals(): true

2.3、hashCode()方法

该方法返回对象的哈希码,它是一个整数值。哈希码在哈希表等数据结构中常用于快速查找和比较对象。在重写equals()方法时,通常也需要重写hashCode()方法,以保证一致性。

package com.kelvin.spiderx.test;

/***
 * @title ObjectTest
 * @desctption Object
 * @author kelvin
 * @create 2023/7/15 12:06
 **/
public class ObjectTest {
    
    

    public static void main(String[] args) {
    
    
        // 创建一个对象
        Person person = new Person("Kelvin", 25);
        Person newPerson = new Person("Kelvin", 25); 

        // 调用hashCode()方法
        int hashCode = person.hashCode();
        System.out.println("hashCode(): " + hashCode);

        // 调用hashCode()方法
        int newHashCode = newPerson.hashCode();
        System.out.println("newHashCode(): " + newHashCode);
    }
}

class Person {
    
    
    private String name;
    private int age;

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

结果:

hashCode(): 366712642
newHashCode(): 1829164700

2.3.1、溯源

通过Idea的快捷键(ctrl + 鼠标左键),选中【person.hashCode】,会跳转到Person类的父类Obejct的hashCode方法(参考 System.identityHashCode 信息)。

public class Object {
    
    

        /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * .........
     * @return  a hash code value for this object.
     * @see     java.lang.Object#equals(java.lang.Object)
     * @see     java.lang.System#identityHashCode
     */
    public native int hashCode();
}

public final class System {
    
    
	public static native int identityHashCode(Object x);
}

2.3.2、重写hashCode方法,根据类里属性值去生成hashCode

重写hashCode方法后,对类里属性值去生成hashCode,如果2个类里属性的值相等,生成的hashCode也会相等。


public class ObjectTest {
    
    

    public static void main(String[] args) {
    
    
        // 创建一个对象
        Person person = new Person("Kelvin", 25);
        Person newPerson = new Person("Kelvin", 25); 

        // 调用hashCode()方法
        int hashCode = person.hashCode();
        System.out.println("hashCode(): " + hashCode);

        // 调用hashCode()方法
        int newHashCode = newPerson.hashCode();
        System.out.println("newHashCode(): " + newHashCode);
    }
}

class Person {
    
    
    private String name;
    private int age;

    public Person(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }
    
    @Override
    public int hashCode() {
    
    
        return Objects.hash(name, age);
    }
}

运行结果:

hashCode(): 838204497
newHashCode(): 838204497


总结

除了上述方法之外,Object类还提供了一些其他的通用方法,如clone()、finalize()、getClassLoader()等。

由于所有类都直接或间接继承自Object类,因此Object类的方法可以在任何对象上使用。但是,需要注意的是,在重写Object类的方法时,应该按照特定的需求和语义来实现,以确保正确的行为。

猜你喜欢

转载自blog.csdn.net/s445320/article/details/131737653