Java基础 —— Object类

java.lang
类 Object
java.lang.Object

public class Object类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。

Object类的成员方法:

  • public int hashCode() //返回该对象的哈希码值。
  • public final Class getClass() //返回此 Object 的运行时类。
  • public String toString() //返回该对象的字符串表示。
  • public boolean equals(Object obj) //指示其他某个对象是否与此对象“相等”。
  • protected void finalize() //当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
  • protected Object clone() //创建并返回此对象的一个副本。

1.public int hashCode()

返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
hashCode 的常规协定是:
在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)

返回:
此对象的一个哈希码值。

简单理解:
哈希值是根据哈希算法计算出来的一个值,这个值和地址有关,但是不是实际的地址值,可以理解为“地址值”

Java代码:

public class ObjectDemo {
    public static void main(String[] args){
        ObjectDemo obj1 = new ObjectDemo();
        System.out.println(obj1.hashCode());    //2070273556 obj1的哈希码值
        ObjectDemo obj2 = new ObjectDemo();
        System.out.println(obj2.hashCode());    //1557606998 obj2的哈希码值,与obj1的地址不同,不是同一对象
        ObjectDemo obj3 = obj1;
        System.out.println(obj1.hashCode());    //2070273556 哈希码与obj1的相同,只想同一对象
    }
}

2.public final Class getClass()

返回此 Object 的运行时类。返回的 Class 对象是由所表示类的 static synchronized 方法锁定的对象。
实际结果类型是 Class,其中 |X| 表示清除表达式中的静态类型,该表达式调用 getClass。 例如,以下代码片段中不需要强制转换:

Number n = 0; 
Classextends Number> c = n.getClass();

返回:
表示此对象运行时类的 Class 对象。

简单理解:
对象调用getClass()方法,返回一个对应类的字节码文件对象

Java代码:

public class ObjectDemo {
    public static void main(String[] args)
        ObjectDemo od = new ObjectDemo();
        Class c = od.getClass();
        //调用Class类的public String getName()方法获取类名
        String cName = c.getName();
        System.out.println(cName);          //com.xxx.Xxx.ObjectDemo
    }
}   

3.public String toString()

返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:

getClass().getName() + '@' + Integer.toHexString(hashCode())

返回:
该对象的字符串表示形式。

简单理解:
对象调用toString()方法,返回一个该方法的”类名@地址”,例如:com.xxx.Xxx.ObjectDemo@262f6be5

Object类中该方法的实现this.getClass().getName()+"@"+Integer.toHexString(this.hashCode())与使用this.toString()方法一样,返回“类名@地址”

Demo d = new Demo();
d.setName("test");
d.setAge(30);
System.out.println(d.getClass().getName()+"@"+Integer.toHexString(d.hashCode()));
System.out.println(d.toString());

类默认继承Object的toString()方法,但返回的值没有多少利用价值,通常需要重写该方法,例如:

@Override
public String toString() {
    return "Demo{name="+ "\'" + name + '\'' +", age=" + age + "}";
}

重写toString()方法后,既可以使用对象调用,也可以直接输出对象(默认调用toString())

Demo d = new Demo();
d.setName("test");
d.setAge(30);
System.out.println(d.toString());       //Demo{name='test', age=30}
System.out.println(d);                  //Demo{name='test', age=30}

4.public boolean equals(Object obj)

指示其他某个对象是否与此对象“相等”。

equals 方法在非空对象引用上实现相等关系:

  • 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
  • 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
  • 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
  • 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
  • 对于任何非空引用值 x,x.equals(null) 都应返回 false。

Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。

注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。

先看源码

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

简单理解:
==:
基本类型:比较的是值是否相等
引用类型:比较的是地址值是否相同
equals:
引用类型:默认情况下,比较的是地址值
不过我们可以根据情况重写该方法,一般重写都是自动生成,比较对象的成员变量是否相同
Java代码:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Demo)) return false;
    Demo demo = (Demo) o;
    return getAge() == demo.getAge() && Objects.equals(getName(), demo.getName());
}

5.protected void finalize()

当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。
finalize 的常规协定是:当 JavaTM 虚拟机已确定尚未终止的任何线程无法再通过任何方法访问此对象时,将调用此方法,除非由于准备终止的其他某个对象或类的终结操作执行了某个操作。finalize 方法可以采取任何操作,其中包括再次使此对象对其他线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象之前执行清除操作。例如,表示输入/输出连接的对象的 finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象之前中断连接。
Object 类的 finalize 方法执行非特殊性操作;它仅执行一些常规返回。Object 的子类可以重写此定义。
Java 编程语言不保证哪个线程将调用某个给定对象的 finalize 方法。但可以保证在调用 finalize 时,调用 finalize 的线程将不会持有任何用户可见的同步锁定。如果 finalize 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止。
在启用某个对象的 finalize 方法后,将不会执行进一步操作,直到 Java 虚拟机再次确定尚未终止的任何线程无法再通过任何方法访问此对象,其中包括由准备终止的其他对象或类执行的可能操作,在执行该操作时,对象可能被丢弃。
对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。
finalize 方法抛出的任何异常都会导致此对象的终结操作停止,但可以通过其他方法忽略它。

抛出:
Throwable - 此方法抛出的 Exception

简单理解:
当垃圾回收器确定不存在该对象的更多引用时,由对象的垃圾回收器调用此方法,用于垃圾回收,但是什么时候回收不确定

6.protected Objectclone()

protected Object clone() throws CloneNotSupportedException

创建并返回此对象的一个副本。“副本”的准确含义可能依赖于对象的类。这样做的目的是,对于任何对象 x,表达式:
x.clone() != x
为 true, 表达式:
x.clone().getClass() == x.getClass()
也为 true,但这些并非必须要满足的要求。一般情况下:
x.clone().equals(x)
为 true,但这并非必须要满足的要求。

按照惯例,返回的对象应该通过调用 super.clone 获得。如果一个类及其所有的超类(Object 除外)都遵守此约定,则x.clone().getClass() == x.getClass()。

按照惯例,此方法返回的对象应该独立于该对象(正被复制的对象)。要获得此独立性,在 super.clone 返回对象之前,有必要对该对象的一个或多个字段进行修改。这通常意味着要复制包含正在被复制对象的内部“深层结构”的所有可变对象,并使用对副本的引用替换对这些对象的引用。如果一个类只包含基本字段或对不变对象的引用,那么通常不需要修改 super.clone 返回的对象中的字段。
Object 类的 clone 方法执行特定的复制操作。首先,如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。注意,所有的数组都被视为实现接口 Cloneable。否则,此方法会创建此对象的类的一个新实例,并像通过分配那样,严格使用此对象相应字段的内容初始化该对象的所有字段;这些字段的内容没有被自我复制。所以,此方法执行的是该对象的“浅表复制”,而不“深层复制”操作。
Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。

返回:
此实例的一个副本。
抛出:
CloneNotSupportedException - 如果对象的类不支持 Cloneable 接口,则重写 clone 方法的子类也会抛出此异常,以指示无法复制某个实例。

简单理解;
对象调用clone()创建并返回该对象的一个副本,当进行副本数据操作时,原来的对象不受影响

注意:当类要调用该方法时,必须重写clone()方法,实现Cloneable接口(该接口没有方法,是标记接口)
Java代码:

class Demo implements Cloneable{
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

你可能感兴趣的:(java基础)