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修饰的方法。
其中,两个protected方法没有实现,其他的都有;线程相关的方法以及getClass()不支持重写(自定义),其他的都支持
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