JDK源码阅读:Object类阅读笔记
Object
1. @HotSpotIntrinsicCandidate
@HotSpotIntrinsicCandidate
public final native Class<?> getClass();
使用@HotSpotIntrinsicCandidate注解标注的方法,表示JVM可能为该方法提供了一些基于CPU指令的高效实现,而非使用Java的实现。
2. native方法
getClass()、hashCode()、clone()、notify()等方法的默认实现都是native方法
3. equals方法
equals()方法默认实现
public boolean equals(Object obj) {
return (this == obj);
}
4. clone方法
clone()方法默认是native实现,且默认是一个浅拷贝。但要调用这个方法,要求类实现Clonable接口,否则会抛出CloneNotSupportedException异常。即使Clonable没有定义任何方法。
public interface Cloneable {
}
下面是一个简单的示例
public class Test implements Cloneable{
public int a = 10;
public static void main(String[] args) {
try {
Test test = new Test();
Object clone = test.clone();
System.out.println(clone.getClass());
System.out.println(test.getClass());
System.out.println(test.a);
Test toClone = (Test)clone;
System.out.println(toClone.a);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
// 输出
class Test
class Test
10
10
6. toString方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
默认实现返回类名+十六进制哈希码
7. notify和notifyAll方法
唤醒在对象监视器上等待的线程。
有下面这些方法令当前线程获得一个对象的监视器
- 执行synchronized方法
- 执行synchronized块
- 执行synchronized的静态方法(获得的是当前类的class对象的监视器)
8. wait方法
下面是一个带纳秒参数nano的wait方法
public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
if (timeoutMillis < 0) {
throw new IllegalArgumentException("timeoutMillis value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
timeoutMillis++;
}
wait(timeoutMillis);
}
我们看到第三个if判断,假如nano参数大于0且timeoutMillis参数未满,所做的直接是令timeoutMillis参数自增。最后直接调用wait(timeoutMillis),这简直是对程序员的欺骗。注:1ms = 1000000ms
下面的这段代码是一段示例代码。推荐的等待方法是在调用wait的while循环中检查等待的条件,如下例所示。 这种方法避免了可能由虚假唤醒引起的问题。
虚假唤醒:线程可以在没有被通知、中断或超时的情况下唤醒
synchronized (obj) {
while (<condition does not hold> and <timeout not exceeded>) {
long timeoutMillis = ... ; // recompute timeout values
int nanos = ... ;
obj.wait(timeoutMillis, nanos);
}
... // Perform action appropriate to condition or timeout
}
9. finalize方法
@Deprecated(since="9")
protected void finalize() throws Throwable { }
显然我们看到,通过@Deprecated(since="9")注解,标记了finalize()方法自JDK9开始被弃用。
不推荐使用的原因
finalize()方法不能保证执行。
还有另外一个方法能够回收对象,Runtime.getRuntime().runFinalization(); 但是这只能保证GC做出最大的努力,但是我们也不能finalize方法都能执行。我们还有一种方式能够保证执行finalize()方法,Runtime.runFinalizersOnExit(true),这个方法已经被JDK弃用,因为这种方法本质上是不安全的,可能导致finalizers方法被活对象调用而其他线程正在并行操作这个对象,从而导致不正确的行为或者死锁。finalize()方法不像构造方法在链中工作,意味着像当你调用构造方法的时候,超类中的构造方法也会被隐含的调用,但是在finalize()方法的这种情况中,这种隐含的调用不会发生。超类中的finalize()方法需要显示的调用。假设,你创建了一个类并且小心翼翼的写了finalize()方法。一些人来extend了你的类,但是在子类中的finalize()块中没有调用super.finalize()方法。然后超类中finalize()方法将永远都不会被调用。
任何有finalize()方法抛出的异常都会被GC线程忽略而且不会被进一步传播,事实上也不会在日志文件上记录下来。
正确的姿势
- 要在finalize()方法中一直调用super.finalize()。
- 考虑到不可预测预测性,不要在时间要求高的应用中使用finalize()。
- 不要使用Runtime.runFinalizersOnExit(true);方法,因为你可能将你的系统置于危险之中。
- 尝试遵循下边的模板使用finalize()方法。
@Override
protected void finalize() throws Throwable{
try{
//release resources here
}catch(Throwable t){
throw t;
}finally{
super.finalize();
}
JDK源码阅读:Object类阅读笔记的更多相关文章
- JDK源码之Integer类分析
一 简介 Integer是int基本类型的包装类,同样继承了Number类,实现了Comparable接口,String类中的一些转化方法就使用了Integer类中的一些API,且fianl修饰不可继 ...
- 【java基础之jdk源码】Object
最新在整体回归下java基础薄弱环节,以下为自己整理笔记,若有理解错误,请批评指正,谢谢. java.lang.Object为java所有类的基类,所以一般的类都可用重写或直接使用Object下方法, ...
- JDK源码之Double类&Float类分析
一 概述 Double 类是基本类型double的包装类,fainl修饰,在对象中包装了一个基本类型double的值.Double继承了Number抽象类,具有了转化为基本double类型的功能. 此 ...
- JDK源码之String类解析
一 概述 String由final修饰,是不可变类,即String对象也是不可变对象.这意味着当修改一个String对象的内容时,JVM不会改变原来的对象,而是生成一个新的String对象 主要考虑以 ...
- JDK源码之Byte类分析
一 简介 byte,即字节,由8位的二进制组成.在Java中,byte类型的数据是8位带符号的二进制数,以二进制补码表示的整数 取值范围:默认值为0,最小值为-128(-2^7);最大值是127(2^ ...
- JDK源码之Boolean类分析
一 简介 boolean类型的封装类,将基本类型为boolean的值包装在一个对象中,实现序列化接口,和Comparable接口 额外提供了许多便捷方法,比较简单,直接贴代码分析 二 源码分析 //t ...
- JDK源码之AbstractStringBuilder类分析
一 概述 二 实现接口 AbstractStringBuilder实现了两个接口: Appendable 概述: Appendable的实现类的对象可以附加字符序列和值. 要追加的字符应该是Unico ...
- yii2 源码分析 object类分析 (一)
转载请注明链接http://www.cnblogs.com/liuwanqiu/p/6737327.html yii2基本上所有的类都是继承的object类,下面就来分析一下object类吧 obje ...
- 源码学习-Object类
1.Object类是Java所有类的超类 2.查看Object的属性和方法,发现Object类没有属性,只有13个方法,其中7个本地方法. 3.接下来看具体的方法 3.1 Object() 默认的构造 ...
- jdk源码理解-String类
String类的理解 简记录一下对于jdk的学习,做一下记录,会持续补充,不断学习,加油 1.String的hash值的计算方法. hash值的计算方法多种多样,jdk中String的计算方法如下,比 ...
随机推荐
- [TensorFlow2.0]-手写神经网络实现鸢尾花分类
本人人工智能初学者,现在在学习TensorFlow2.0,对一些学习内容做一下笔记.笔记中,有些内容理解可能较为肤浅.有偏差等,各位在阅读时如有发现问题,请评论或者邮箱(右侧边栏有邮箱地址)提醒. 若 ...
- 用于在公网环境下测试的Telnet/SSH服务器
google: public telnet server list for example: telnet nethack.alt.org ssh nethack@alt.org
- 线程队列 concurrent 协程 greenlet gevent
死锁问题 所谓死锁:是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...
- HTML5内嵌文本编辑器
1.这个编辑器用的是KindEditor 先看下效果: 2.准备: a):从官网下载KindEditor--->http://kindeditor.net/down.php b):解压到桌面测试 ...
- 题解 math
传送门 赛时用一个奇怪的方法过掉了 首先\(b_i\)的有效范围是\([0, k-1]\) 发现不同的\(a_i*b_i\)会有很多重的 考虑把\(a_i\%k\),然后由小到大排序 按顺序扫,如果某 ...
- 踩坑记录之 -- String.IndexOf 在 .Net5 和 .Netcore3 中返回值不一样
.Net Core3.1 下 运行此段代码 class Program { static void Main(string[] args) { // .NET Core 3.1 string s = ...
- mysql查询附近门店
mysql 查询一个地点(经纬度) 附近N公里内的数据.(根据一个地点的经纬度查询这个地点方圆几公里内的数据)1.创建测试表 CREATE TABLE `location` ( `id` int(10 ...
- WPF 窗口 最前端 Topmost Owner
WPF 中,如果我们想把某个窗口一直置于最前端,那么可以设置Topmost=true; 但是,这样就会有另外一个问题,就时你这个窗口,会一直处于最顶层,即使你想切换到其他程序的时候. 比如,你自己写的 ...
- 彻底搞懂volatile关键字
对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好起来却不是一件容易的事.这篇文章将从多个方面来讲解volatile,让你对它更加理解. ...
- Redis常用技术
Xml配置: <?xml version='1.0' encoding='UTF-8' ?> <!-- was: <?xml version="1.0" e ...