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的计算方法如下,比 ...
随机推荐
- 第一个Java文件
HelloWorld 1.新建一个文件夹,用来存放java文件的 2.用subline来编辑第一个Java文件 要注意的是java的文件名为.java 我们自定义的文件名是Hello 3.编写第一个j ...
- NSIS 制作自动升级包
1:首先定义基础变量 !define PRODUCT_NAME "XXX"//补丁名称 !define PRODUCT_VERSION "3"//版本号 !de ...
- [11 Go语言基础-可变参数函数]
[11 Go语言基础-可变参数函数] 可变参数函数 什么是可变参数函数 可变参数函数是一种参数个数可变的函数. 语法 如果函数最后一个参数被记作 ...T ,这时函数可以接受任意个 T 类型参数作为最 ...
- Java Lambda 表达式源码分析
基本概念 Lambda 表达式 函数式接口 方法引用 深入实现原理 字节码 为什么不使用匿名内部类? invokedynamic 总结 参考链接 GitHub 项目 Lambda 表达式是什么?JVM ...
- DVWA-全等级文件包含
DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...
- Python中用max()筛选出列表中出现次数最多的元素
1 List = [1,2,3,4,2,3,2] # 随意创建一个只有数字的列表 2 maxTimes = max(List,key=List.count) # maxTimes指列表中出现次数最多的 ...
- NOIP 模拟 $13\; \text{玄学题}$
题解 题如其名,是挺玄学的. 我们发现每个值是 \(-1\) 还是 \(1\) 只与它的次数是奇是偶有关,而 \(\sum_j^{j\le m}d(i×j)\) 又只与其中有多少个奇数有关 对于 \( ...
- mysql悲观锁和乐观锁
悲观锁 查出来的数据必须是根据索引查出来的,不然锁表. # 语法 select * from table where id = 1 for update; 乐观锁 使用一个标识 cas 比较后替换 如 ...
- javascript,html,正则表达式,邮箱密码验证
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- spring boot , spring security 安全的认证
pom 文件 ------------------------------------------------------------------- <dependencies> < ...