[Java基础] 第一章 String类应用及分析
[Java基础] 第二章 数组应用及源码分析
[Java基础] 第三章 StringBuffer 和 StringBuilder 类应用及源码分析
[Java基础] 第四章 Object 类应用
Java中的Object类是所有类的根类,它位于Java类层次结构的顶部。每个类都隐式地直接或间接地继承自Object类。Object类提供了一些通用的方法,可以在所有的Java对象中使用。
Object 类位于 java.lang 包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类。
Object 类可以显式继承,也可以隐式继承。
public class Person extends Object{
}
public class Person{
}
序号 | 构造方法 & 描述 |
---|---|
1 | 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类的方法时,应该按照特定的需求和语义来实现,以确保正确的行为。
该方法返回对象的字符串表示形式。默认情况下,它返回类名和对象的哈希码。通常,我们可以重写这个方法来返回我们自定义的字符串表示形式。
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
通过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);
}
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]
该方法用于比较两个对象是否相等。默认情况下,它比较对象的引用是否相等,即是否指向同一个对象。通常,我们需要根据对象的内容重写这个方法,以实现我们自己的相等逻辑。
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
通过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);
}
重写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
该方法返回对象的哈希码,它是一个整数值。哈希码在哈希表等数据结构中常用于快速查找和比较对象。在重写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
通过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);
}
重写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类的方法时,应该按照特定的需求和语义来实现,以确保正确的行为。