Object源码阅读笔记

关于Object类,我们需要知道几点:

(1)Object类是Java中所有类的父类,在jdk9,它的位置位于java.base模块的java.lang包中。若用树形结构来描述Java类分类等级结构,则Object应该是树根root。

(2)Object类型的变量可以存储任意类型的引用(子类使用继承自Object的clone()时,要注意返回的副本对象的引用是Object类型,必须用Object类型的变量存储or进行类型转换),包括任意类型可以存储的null值,反之则不行。Object类型的变量创建时应注意先声明,事实上Java中所有类型的变量都需要先声明再使用。

Object obj;
System.out.println("obj: " + obj);
//没有声明会出错:可能尚未初始化变量

要判断某个引用是否属于某个类型,可以通过instanceof运算符。

https://mp.csdn.net/postedit/81952931

(3)利用第二点的特性可以用Object来给方法传参,以匹配更多类型的参数

class MyObject {
}

public class ObjectTest {
	public static void main(String[] args) {
		//paraType(null);  
        //错误:Exception in thread "main" java.lang.NullPointerException
		paraType(new Object());
		paraType(new MyObject());
	}
	public static void paraType(Object obj) {
		System.out.println(obj.getClass());
	}
}

注意:paraType(null)出现异常是因为Object的getClass()的调用者不能使空对象

Object类的内部成员如图所示,其中大部分为public、native修饰的方法。

âObjectç±»ç»æâçå¾çæç´¢ç»æ

其中,两个protected方法没有实现,其他的都有;线程相关的方法以及getClass()不支持重写(自定义),其他的都支持

扫描二维码关注公众号,回复: 3082688 查看本文章

1、registerNatives()方法

private static native void registerNatives();   
    static {
        registerNatives();                          
    }
	//类首次加载时执行 
    //虚拟机调用initializeSystemClass方法,即静态初始化程序,来初始化静态变量、调用静态方法

2、Object()构造方法

public Object() {}

3、getClass()方法

    @HotSpotIntrinsicCandidate
    public final native Class<?> getClass();  
    // 用final修饰,说明不可被重写
    // 作用:返回对象的运行时类,返回的Class对象是被表示类的静态同步方法锁定的对象。
    // 这便于进行反射操作,进行动态加载指定的类等操作

Java中,每个类一般只加载一次。当程序编译成class文件之后,要运行时,class文件(从本地文件系统、网络、数据库)通过java.lang.ClassLoader类的class loader对象被加载到JVM——一个类对应一个class loader,可以扩展ClassLoader来得到我们想要的class loader,不过一般不这么做。然后它创建一个java.lang.Class<T>类型的对象,代表JVM中的T类的二进制表示。

Object类的getClass()返回Class类的一个对象的引用,而因为Object是所有类的父类,所以我们可以在任何类型的引用上调用这个方法。当我们在同个类型的多个引用上调用这个方法时,返回的是同一个Class类对象的引用。

注意:并不是所有类都在应用开始时被加载到JVM,只有当一个类被第一次使用时,才会被加载并产生相应的Class对象。

4、hashCode()方法

    /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}. 
     * <p>  
     * The general contract of {@code hashCode} is:  
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
	 * 原则1:一致性————多次调用同一个对象的这个方法,返回的值一样
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
	 * 该整数不需要在 同一个应用的2次执行中 保持一致性
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
	 * 2、如果2个对象equals为true, 那么它们的hashCode为一样的值
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code 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.
	 * 3、不过如果2个对象equals为false, 那么hashCode也可能为一样的值
	 * 开发者应该注意:先使用hashCode进行筛选,可以提高哈希表的性能
     * </ul>
     * <p>
     * As much as is reasonably practical, the hashCode method defined
     * by class {@code Object} does return distinct integers for
     * distinct objects. (The hashCode may or may not be implemented
     * as some function of an object's memory address at some point
     * in time.)
	 * 4、尽可能合理地定义这个方法
	 * 有些类: 不同的对象(内存地址),哈希码不同;
	 * 有些类: 不同的内容, 哈希码不同
     * 根据我们的需要决定是否重写方法,有以上两种情况,不过不管是哪种情况,根据以上第二、三点,
     * 在使用时,(1)我们先用HashCode方法比较两个对象的哈希值是否相等,若不等,则一定不是同一个        
     * 对象or内容相同;反之,进第二步判断
     *(2)再用equals方法比较两个对象是否为同一个对象or内容是否相同,若返回结果为true,则同一个
     *对象or内容相同
     *之所以按照这个规则,我想大概基于两点:i、hashCode其实是将地址or内容采用一种算法进行映射得    
     *到一种编码,而equals则是直接比较两个对象的地址or内容是否相同。 所以,hashCode存在冲突的
     *现象————内容or地址不同的2个对象,hashCode值相同 ii、尽管equals是直接比较,但是其消耗较大
     *所以,先用hashCode有助于提高性能,筛选掉大部分情况(毕竟冲突时小概率事件)
     *
     * @return  a hash code value for this object.  
     * @see     java.lang.Object#equals(java.lang.Object)   对比equals
     * @see     java.lang.System#identityHashCode			对比identityHashCode
     */
    @HotSpotIntrinsicCandidate
    public native int hashCode();
    // 返回对象的哈希码(一个整数值)
	// 显然,本地的hashCode方法 比较的是内存地址(同一性)  重写的话另说
	// identityHashCode方法 用的是本地的hashCode方法 比较的是内存地址(同一性)
    //对于Object or String,注意前者的hashCode、equals、identityHashCode、==都是比较同一性
    //(地址),后者的hashCode、equals比较的是等同性(内容),System.identityHashCode、==补充
    //比较同一性(地址)    

5、equals()方法

/**
     * Indicates whether some other object is "equal to" this one.
     * <p>
     * The {@code equals} method implements an equivalence relation
     * on non-null object references:  注意是非空对象的等价关系,也就是说,null不能调用?
     * <ul>
     * <li>It is <i>reflexive</i>: for any non-null reference value
     *     {@code x}, {@code x.equals(x)} should return
     *     {@code true}.
	 * 性质1、反射性--任何 非空引用 调用自身,返回结果都是true
     * <li>It is <i>symmetric</i>: for any non-null reference values
     *     {@code x} and {@code y}, {@code x.equals(y)}
     *     should return {@code true} if and only if
     *     {@code y.equals(x)} returns {@code true}.
	 * 2、 对称性--两个引用 互相调用,返回结果一样
     * <li>It is <i>transitive</i>: for any non-null reference values
     *     {@code x}, {@code y}, and {@code z}, if
     *     {@code x.equals(y)} returns {@code true} and
     *     {@code y.equals(z)} returns {@code true}, then
     *     {@code x.equals(z)} should return {@code true}.
	 * 3、 传递性
     * <li>It is <i>consistent</i>: for any non-null reference values
     *     {@code x} and {@code y}, multiple invocations of
     *     {@code x.equals(y)} consistently return {@code true}
     *     or consistently return {@code false}, provided no
     *     information used in {@code equals} comparisons on the
     *     objects is modified.
	 * 4、 一致性--两个对象之间的调用  多少次还是那个结果   前提是没有信息被修改
     * <li>For any non-null reference value {@code x},
     *     {@code x.equals(null)} should return {@code false}.
	 * 5、 任意非空引用 调用null   返回的都是false
     * </ul>
     * <p>
     * The {@code equals} method for class {@code Object} implements
     * the most discriminating possible equivalence relation on objects;
     * that is, for any non-null reference values {@code x} and
     * {@code y}, this method returns {@code true} if and only
     * if {@code x} and {@code y} refer to the same object
     * ({@code x == y} has the value {@code true}).
	 * Object的equals实现: 最具有辨别力(其hashCode可能会有冲突的现象)的2个
	 *非空引用 的等价性比较
	 *也就是说,只有x,y都是同一个对象的引用时(指向同一个对象),返回的才是true
     * <p>
     * Note that it is generally necessary to override the {@code hashCode}
     * method whenever this method is overridden, so as to maintain the
     * general contract for the {@code hashCode} method, which states
     * that equal objects must have equal hash codes.
	 * 不管equals方法有没有重写,我们都要重写hashCode方法
	 *从而保证————equal的对象(无重写:内存地址相同,指向同一个对象;有重写:内容相同)
     *具有相同的hashCode值:for 地址or 内容的各个位 + hashCode算法 ==得到 相同的值
     * @param   obj   the reference object with which to compare.
     * @return  {@code true} if this object is the same as the obj
     *          argument; {@code false} otherwise.
     * @see     #hashCode()
     * @see     java.util.HashMap  看看HashMap中的实现原理:基于HashCode()  重复元素
     */
    public boolean equals(Object obj) {
        return (this == obj);   // 比较的是两个对象的内存地址 
		// 前面总是说reference object,也就是引用型数据,而不是基本类型数据(比较简单)
        //基本数据类型一般都是用 ==
    }

6、Clone()方法

/**
     * 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 {@code x}, the expression:
     * <blockquote>
     * <pre>
     * x.clone() != x</pre></blockquote>
	 * (1)clone方法是产生对象的一个独立副本 
     * will be true, and that the expression:
     * <blockquote>
     * <pre>
     * x.clone().getClass() == x.getClass()</pre></blockquote>
     * will be {@code true}, but these are not absolute requirements.
	 * (2)对象x和它clone的独立副本 调用getClass方法 结果一样
     * While it is typically the case that:
	 * 但这些不是绝对的条件(意思是clone可以重写吗?)
     * <blockquote>
     * <pre>
     * x.clone().equals(x)</pre></blockquote>
     * will be {@code true}, this is not an absolute requirement.
	 * x的clone副本 和 自己 equal  但是不是绝对的(意思是如果equal的是地址的话就不一定?)
     * <p>
     * By convention, the returned object should be obtained by calling
     * {@code super.clone}.  If a class and all of its superclasses (except
     * {@code Object}) obey this convention, it will be the case that
     * {@code x.clone().getClass() == x.getClass()}.
	 * 按照惯例,返回的对象应该通过super.clone调用得到
	 *如果一个类和它所有父类遵循这个惯例,那么x.clone().getClass() == x.getClass()
     * <p>
     * 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 {@code super.clone} before 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 {@code super.clone}
     * need to be modified.
	 *按照惯例,返回的对象是独立的
	 *为了实现这个独立性,返回副本之前 有必要修改这个对象的一个or多个元素
	 *通常,这意味着复制组成这个对象深层结构的所有可变元素,并用副本的引用替换这些元素的引用
	 *如果一个类只包含原始字段、不可变元素的引用,那么super.clone返回的对象 没有字段需要修改
	 *大概意思: 浅拷贝  只复制引用的值,没有复制可变元素所引用的对象
     * <p>
     * The method {@code clone} for class {@code Object} performs a
     * specific cloning operation. First, if the class of this object does
     * not implement the interface {@code Cloneable}, then a
     * {@code CloneNotSupportedException} is thrown. Note that all arrays
     * are considered to implement the interface {@code Cloneable} and that
     * the return type of the {@code clone} method of an array type {@code T[]}
     * is {@code 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.
     * <p>
     * The class {@code Object} does not itself implement the interface
     * {@code Cloneable}, so calling the {@code clone} method on an object
     * whose class is {@code Object} will result in throwing an
     * exception at run time.
	 *Object的clone方法实施具体的操作:
	 *1、如果这个对象的类 没有实现Cloneable接口, CloneNotSupportedException异常就会抛出
	 *2、注意所有arrays 应该实现Cloneable接口 T[]返回T[] T是任意引用、基本类型
	 *3、否则,此方法初始化这个对象的新对象+赋值所有字段(但字段的内容不会被克隆)
	 *这也就是浅拷贝,而不是深拷贝操作
	 *4、Object类自己并没有实现Cloneable接口,因此在Object类的对象上调用方法,运行时会抛出异常
     *
     * @return     a clone of this instance.
     * @throws  CloneNotSupportedException  if the object's class does not
     *               support the {@code Cloneable} interface. Subclasses
     *               that override the {@code clone} method can also
     *               throw this exception to indicate that an instance cannot
     *               be cloned.
	 * 当对象的类不支持Cloneable接口时,抛出异常
	 * 重写这个方法的子类 也可以抛出这个异常(以表示这个实例不能被克隆)
     * @see java.lang.Cloneable     对比Cloneable
     */
    @HotSpotIntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;
    //1、一般在原型模式时使用
    //2、使用时需要让被拷贝的对象所属的类实现Cloneable接口,才能调用该方法进行拷贝。

7、toString()方法

/**
     * Returns a string representation of the object. In general, the
	 *返回这个对象的 字符串表示 
     * {@code 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.
     * <p>
     * The {@code toString} method for class {@code Object}
     * returns a string consisting of the name of the class of which the
     * object is an instance, the at-sign character `{@code @}', 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:
	 *返回的字符串包括:类的名字、@、对象的16进制表示的哈希值
     * <blockquote>
     * <pre>
     * getClass().getName() + '@' + Integer.toHexString(hashCode())
	 *类的名字、@、对象的16进制表示的哈希值
     * </pre></blockquote>
     *
     * @return  a string representation of the object.
     */
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
    // 用于显示该对象的内容
    // 一般需要重写

8、notify()方法

/**
     * Wakes up a single thread that is waiting on this object's
     * monitor. If any threads are waiting on this object, one of them
     * is chosen to be awakened. The choice is arbitrary and occurs at
     * the discretion of the implementation. A thread waits on an object's
     * monitor by calling one of the {@code wait} methods.
	 *唤醒在这个对象的监视器上的 一个等待线程
	 *如果有线程在等待队列中等待(通过调用wait方法,一个线程在对象的监视器上等待),其中的一个
	 *被选中唤醒。这种选择是任意的,根据算法进行竞争(最着急的线程)
	 *
     * <p>
     * The awakened thread will not be able to proceed until the current
     * thread relinquishes the lock on this object. The awakened thread will
     * compete in the usual manner with any other threads that might be
     * actively competing to synchronize on this object; for example, the
     * awakened thread enjoys no reliable privilege or disadvantage in being
     * the next thread to lock this object.
	 *唤醒的线程将无法继续(被其他对象使用?在等待) 直到当前线程放弃对这个对象的锁定
	 *被唤醒的线程 以通用的方式 与任何其他(积极竞争同步这个对象的)线程竞争
     *同步,是说没有特权,都有机会成为能够锁定该对象的线程
     * <p>
     * This method should only be called by a thread that is the owner
     * of this object's monitor. A thread becomes the owner of the
     * object's monitor in one of three ways:
	 *这个方法只能被一个线程(这个线程是 对象的监视器的所有者)调用
	 *一个线程可以以3种方式 成为这个对象的监视器的所有者
     * <ul>
     * <li>By executing a synchronized instance method of that object.
     * <li>By executing the body of a {@code synchronized} statement
     *     that synchronizes on the object.
     * <li>For objects of type {@code Class,} by executing a
     *     synchronized static method of that class.
     * 1、在调用notify()之前,线程必须获得该对象的对象级别锁 
     * 2、执行完notify()方法后,不会马上释放锁,要直到退出synchronized代码块,当前线程才会释放
     *锁  
     * 3、notify()一次只随机通知一个线程进行唤醒
     * </ul>
     * <p>
     * Only one thread at a time can own an object's monitor.
	 *原则:一次只能有一个线程 拥有一个对象的监视器
     *
     * @throws  IllegalMonitorStateException  if the current thread is not
     *               the owner of this object's monitor.
	 *如果当前线程 不是这个对象的monitor的所有者,抛出IllegalMonitorStateException
     * @see        java.lang.Object#notifyAll()  对比notifyAll
     * @see        java.lang.Object#wait()       对比wait
     */
    @HotSpotIntrinsicCandidate
    public final native void notify();
    //唤醒对象的等待队列上的 一个线程

9、notifyAll()方法

    public final native void notifyAll();
    //唤醒所有 等待在这个对象的监视器上的线程

10、wait()方法

//第一种实现:使线程进入等待状态,直到被notify or notifyAll调用 or 等待时间达到限定值
//timeout - 要等待的最长时间(以毫秒为单位)。
//nanos - 额外时间(以毫微秒为单位,范围是 0-999999)
//超时时间=1000000*timeout+nanos(毫微秒)。
    public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) {
            timeout++;
        }

        wait(timeout);
    }

//实现二:使线程进入等待状态,直到被notify or notifyAll调用
    public final void wait() throws InterruptedException {
        wait(0);
    }

11、finalize()方法

    @Deprecated(since="9")
    protected void finalize() throws Throwable { }

从Java SE 9开始弃用 

关于native方法

JDK源代码由C++、Java、C、汇编 这四种语言组成。JVM主体是C++写的,JNI部分是C,工具类是Java写的,JVM里混有汇编代码。JNI是Java Native Interface的缩写,从Java 1.1 开始,Java Native Interface (JNI)标准就成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。

"A native method is a Java method whose implementation is provided by non-java code"。一个Native Method是这样的一个java方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。

Native方法:

https://blog.csdn.net/wike163/article/details/6635321

Native方法的使用示例:

https://www.cnblogs.com/HDK2016/p/7226840.html

blog.51cto.com/2301703/1035358

Native方法的内部细节:

wiki.jikexueyuan.com/project/jni-ndk-developer-guide/serchnative.html

https://juejin.im/post/59634a666fb9a06bbf6ffce6

猜你喜欢

转载自blog.csdn.net/sinat_30973431/article/details/81784527