Object类包含那些方法?都有什么作用?(上)

Object类包含那些方法?都有什么作用?(上)

本文优先参考jdk1.8文档,辅以Java核心技术和Java编程思想,补充以各种博客碎片知识,希望可以以面试题为导向,解读java基础知识。

Object类简介

Document描述:
Object类是类层级(class hierarchy)中的根.每个类都以Object类作为基类。所有的类以及数组都实现Object类的方法。

方法概述

2.1 getClass

public final native Class<?> getClass();

Returns the runtime class of this Object. The returned Class object is the object that is locked by static synchronized methods of the represented class.

The actual result type is Class<? extends |X|> where |X| is the erasure of the static type of the expression on which getClass is called. For example, no cast is required in this code fragment:

Number n = 0; 
Class<? extends Number> c = n.getClass(); 

返回当前 Object的运行时类runtime class. 返回的类对象是当前类的 static synchronized 方法锁定的对象。

实际返回的结果是Class <? extends |x|>,其中|X|是一种类,如下代码段所示。

// Class <? extends String>是getClass()的返回值
Class<? extends String> c = "".getClass(); // class java.lang.String

native方法是非Java语言实现的代码,供Java程序调用的,因为Java程序是运行在JVM虚拟机上面的,要想访问到比较底层的与操作系统相关的就没办法了,只能由靠近操作系统的语言来实现。

Notes:此方法在学习反射时会用到。

2.2 hashCode

public native int hashCode();

Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by [HashMap]

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equalscomparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the [equals(java.lang.Object)]method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language.)

返回对象的hashCode。

hashCode的一般约定:

  1. 只要在Java应用程序执行期间在同一对象上多次调用它, hashCode方法就必须始终返回相同的整数,前提是不修改该对象的equals比较中使用的信息。 从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。

  2. 如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。

  3. 根据equals(Object)方法,如果两个对象不相等,则不需要在两个对象中的每一个上调用hashCode方法都必须产生不同的整数结果。 但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

    在合理可行的情况下,由Object类定义的hashCode方法确实为不同的对象返回不同的整数。这通常是通过将对象的内部地址转换为整数来实现的,但这种实现技术并不是Java™编程语言所要求的

例子:

		MyObject o1 = new MyObject();
        MyObject o2 = new MyObject();
        MyObject o3 = o2;
        System.out.println("o1's hashCode:" + o1.hashCode());
        System.out.println("o1's output:" + o1);
        System.out.println("o2's hashCode:" + o2.hashCode());
        System.out.println("o2's output:" + o2);
        System.out.println("o3's hashCode:" + o3.hashCode());
        System.out.println("o3's output:" + o3);
/*
o1's hashCode:312714112
o1's output:cn.ravi.basic.MyObject@12a3a380
o2's hashCode:692404036
o2's output:cn.ravi.basic.MyObject@29453f44
o3's hashCode:692404036
o3's output:cn.ravi.basic.MyObject@29453f44
*/

Notes:hashcode()方法主要为了给Hash tables系列的集合(HashMap、HashTable、HashSet)提供支持。两个对象equals—>hashcode相等,但是hashcode相等并不能推出两个对象equals。原因是hashcode的计算方法是对象的某种属性进行的数学运算后得到的值,难免会出现两个不同的对象(equals返回false)得出一样的hashcode(通常情况概率极小)

2.3 equals

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

Indicates whether some other object is “equal to” this one.

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only ify.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z)returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).

Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

equals方法实现了对非空对象引用的等价关系。

对于equals的要求:

  1. 自反性:对于任何非空引用x,x.equals(x)应该返回 true
  2. 对称性:对于任何引用x和y,当且仅当y.equals(x)返回 truex.equals(y)也应该返回 true
  3. 传递性:对于任何引用x和y和z,当且仅当x.equals(y)返回 truey.equals(z)返回 truex.equals(z)也应该返回 true
  4. 一致性:如果x和y的引用的对象没有发生变化,反复调用x.equals(y)应该返回相同的结果
  5. 对于任何非空引用x,x.equals(null)应该返回 false

Object类equals方法实现:对于任何非空的引用值x和y,当且仅当x和y指向同一个对象时,该方法返回true(x == y的值为true)

注意:只要重写hashCode方法,就必须重写这个方法,这样才能保持hashCode方法的一般契约,即相等的对象必须有相等的哈希代码。

		MyObject o1 = new MyObject(32);
        MyObject o2 = new MyObject(32);

        System.out.println("o1's hashCode:" + o1.hashCode());
        System.out.println("o2's hashCode:" + o2.hashCode());
        System.out.print("o1 == o2:");
        System.out.println(o1==o2);
        System.out.print("o1.equals(o2): ");
        System.out.println(o1.equals(o2));
/*
o1's hashCode:312714112
o2's hashCode:692404036
o1 == o2:false
o1.equals(o2): true
*/

实现equals:

		@Override
    public boolean equals(Object obj) {
        /* 1、检测 this 和 obj 是否引用同一个对象 */
        if (this == obj) {
            return true;
        }

        /* 2、检测 obj 是否为 null,如果为 null,返回 false */
        if (obj == null) {
            return false;
        }

        /* 3、检测 obj 和 this 是否属于同一个类 */
        boolean b = obj instanceof MyObject;
        if (!b) {
            return false;
        }

        /* 4、转型 */
        MyObject other = (MyObject) obj;

        /* 5、比较所有域 */
        return this.nums == other.nums;
    }

Notes:通过上面的例子可以知道:equals判断值,==判断引用地址

2.4 clone

推荐阅读1详解Java中的clone方法 – 原型模式

推荐阅读2 03.学习浅拷贝和深拷贝的正确方式

这是一个protected方法。所以我们可以在子类中使用它。

在java语言中,创建对象可以通过:

  1. 使用new操作符创建一个对象

  2. 使用clone方法复制一个对象

使用clone方法而不是new一个对象的原因:
clone 方法是native 方法,效率要远高于非native的方法。

protected native Object clone() throws CloneNotSupportedException;

Creates and returns a copy of this object. The precise meaning of “copy” may depend on the class of the object. The general intent is that, for any object x, the expression:

创建并返回当前对象的副本,意味着“副本”依赖当前类的对象。对于任何对象x而言,下面的表达式成立:

x.clone() != x

will be true, and that the expression:

x.clone().getClass() == x.getClass()

will be true, but these are not absolute requirements. While it is typically the case that:

但是这些也不是强制的要求。

x.clone().equals(x)

will be true, this is not an absolute requirement.这也不是强制要求。

By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case that x.clone().getClass() == x.getClass().

按照惯例,返回对象应该通过调用super.clone函数来构造。如果一个类和它的所有父类(除了Object)都遵循这个约定,那么x.clone().getClass() == x.getClass()将成立。

By convention, the object returned by this method should be independent of this object (which is being cloned). To achieve this independence, it may be necessary to modify one or more fields of the object returned by super.clonebefore returning it. Typically, this means copying any mutable objects that comprise the internal “deep structure” of the object being cloned and replacing the references to these objects with references to the copies. If a class contains only primitive fields or references to immutable objects, then it is usually the case that no fields in the object returned by super.clone need to be modified.

按照惯例,返回的对象应该和原始对象是独立的。为了实现这种独立性,后续在调用super.clone得到拷贝对象并返回之前,应该对内部深层次的可变对象创建副本并指向克隆对象的对应属性的引用。如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下,由super.clone返回的对象中没有字段需要被修改。

The method clone for class Object performs a specific cloning operation. First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown. Note that all arrays are considered to implement the interface Cloneable and that the return type of the clone method of an array type T[]is T[] where T is any reference or primitive type. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a “shallow copy” of this object, not a “deep copy” operation.

Object类的方法 clone()执行了一个特定的克隆操作。首先,如果这个对象的类没有实现Cloneable接口,那么会抛出一个CloneNotSupportedException。注意,所有的数组都被认为实现了Cloneable接口,并且数组类型T[]clone方法的返回类型是T[],其中T是任何引用或原始类型。对于非数组对象,该方法将创建一个新的该对象的类的实例,并且用该对象的相应字段的内容来初始化它的所有字段,就像通过赋值一样;字段的内容本身没有被克隆。因此,这个方法执行了这个对象的 “浅拷贝”,而不是 "深拷贝 "操作。

The class Object does not itself implement the interface Cloneable, so calling the clone method on an object whose class is Object will result in throwing an exception at run time.

Object本身没有实现Cloneable接口,因此调用Object类对象的clone 方法将会抛出运行时异常。

Java中的我们常常需要复制的类型有三种:

1:8种基本类型,如int,long,float等;

2:复合数据类型(数组);

3:对象变量

基本数据类型存放在栈中;而对象实例和数组都在堆上分配。对于基本数据类型我们不需要考虑浅拷贝和深拷贝,使用等号便可复制值。而对象实例和数组则需要考虑浅复制和深复制问题。

举例:

例子图解

2.4 toString

	public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

Returns a string representation of the object. In general, the toString method returns a string that “textually represents” this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character ``@`’, and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

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

Returns:

  • a string representation of the object.

返回一个代表对象的字符串。其结果应该是一个简明但内容丰富的表述,便于人们阅读。建议所有的子类都覆盖这个方法。

Object的toString方法,默认返回字符串内容包含:该对象所属类@该对象哈希值的无符号十六进制。

未完待续…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值