文章目录
Object类
- 万物父类,用源码解释来说就是
is the root of the class hierarchy.
registerNatives()
- 关于native,是Java的本地方法,通过JNI调用C系列的dll文件实现。
/**
* 一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用
*/
private static native void registerNatives();
/**
* Object 初始化的时候自动调用registerNatives();
*/
static {
registerNatives();
}
getClass()
/**
* 返回运行时类的class,输出的话就是:class java.lang.Object
* @return
*/
public final native Class<?> getClass();
- Returns the runtime class of this {@code Object}.
- 返回这个对象的类型,注意这里是对象,如果是int a=0;的a不是对象,不具有 getClass()方法
- 但是像String这种封装的类所产生的对象是有的。
hashCode()
- 是个接口,返回一串Hash码:
a hash code value for this object.
- 解释中说是为需要hash code的类准备的方法,如HashMap等
This method is supported for the benefit of hash tables such as those provided by {@link java.util.HashMap}.
public native int hashCode();
equals()
- 这里有段很重要的话:这段话衍生的问题我在面试中遇见过~
- 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.```
necessary to override the {@code hashCode}
使用equals()就必须同时override hashCode(),也就是两个对象equals的前提是他们拥有同一个hash code,这个涉及到hashCode的常规协定
hashCode 的常规协定是:
- 1.在应用程序执行期间,如果一个对象用于equals()方法的属性没有被修改的话,
那么要保证对该对象多次返回的hashcode值要相等。- 2.如果2个对象通过equals()方法判断的结果为true,那么要保证二者的hashcode值相等。
- 3.如果2个对象通过equals()方法判断的结果为false,那么对二者hashcode值是否相等并没有明确要求。
如果不相等,那么能够提升散列表的性能。
- 这里比较的是对象的内存地址,跟String.equals方法不同,它比较的只是对象的值
public boolean equals(Object obj) {
return (this == obj);
}
clone()
- 如果类没有实现clone方法,则会抛出CloneNotSupportedException错误,所有数组(arrays)都实现了cloneable接口
/**
* 如果类没有实现clone方法,则会抛出CloneNotSupportedException错误,所有数组(arrays)都实现了cloneable接口
* @return
* @throws CloneNotSupportedException
*/
protected native Object clone() throws CloneNotSupportedException;
Clone 有关的几个问题(速度与深浅复制)
- 问题1:对象的创建有多中方式,类似 new 、getInstance、clone等 clone有什么好处?
- 参考大佬的测试代码,调用底层dll,快:
public class ObjectCloneTest1 {
static final int N = 100000;
public static void main(String[] args) {
final Date date = new Date();
{
final long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
Date date2 = (Date) date.clone();
}
final long endTime = System.currentTimeMillis();
System.out.println("clone:" + (endTime - startTime) + "ms");
}
{
final long startTime = System.currentTimeMillis();
for (int i = 0; i < N; i++) {
final Calendar cal = Calendar.getInstance();
cal.setTime(date);
final Date date2 = cal.getTime();
}
final long endTime = System.currentTimeMillis();
System.out.println("Calender.setTime:" + (endTime - startTime) + "ms");
}
}
}
输出是:
clone:8ms
Calender.setTime:153ms
- 问题2:对象调用clone方法生成的对象 和 原对象是否还有什么关联关系?
- Object是属于浅复制,新(拷贝产生)、旧(元对象)对象不同,但是内部如果有引用类型的变量,新、旧对象引用的都是同一引用。
- 问题3 : 对象clone存在 “浅复制”、“深复制”概念,怎么区分?
- 需要区别2个对象是否存在相同的引用或对应的内存地址是否存在共用情况,若存在则 该次clone为 “浅复制”,否则为“深复制”, 而且Object的clone方法是属于 “浅复制”
- 就比如:Person A 和Person B , A==B是false(地址不同) 但是A.getName()==B.getName()(地址同)是true,这是浅复制,深复制的话,就连name也复制了。
toString
- toString没有重写的话就是如下,类名@hashCode
- 但是我们一般会重写toString,这是个很重要的方法
public String toString() {
return getClass( ).getName( ) + "@" + Integer.toHexString(hashCode( ));
}
notify、notifyAll与wait
- 多线程相关内容,注释是我目前的理解
- 顺便提一句,final关键词表示不能被重写
/**
* 1、唤醒一个在次对象监视器wait的线程
* 2、线程被唤醒且被执行的条件是,当前线程释放了运行时上的锁
* 3、被唤醒的线程会与需要相同资源的线程进行竞争
*/
public final native void notify();
/**
* 同notify,只不过是唤醒此对象监视器上的所有线程
*/
public final native void notifyAll();
/**
* 1、使得当前运行的线程进入等待状态(进入等待池)
* 2、当前线程必须拥有此对象的监视器
* 3、当线程被唤醒、或者timeout=0(等待时间到了),会重新进入运行池
* 4、如果被interrupted,即中断了,则抛出InterruptedException,如果是等待状态被中断,则等到恢复运行的时候抛出。
* @param timeout
* @throws InterruptedException
*/
public final native void wait(long timeout) throws InterruptedException;
/**
* 1、使得当前线程等待,直到其他线程调用notify(或notifyALl),或等待时间已到
* 2、实现上很简单,nanos>0即可,在jdk1.7及一下nanos内部似乎是变过的,具体代码如下
* if(nanos >= 500000 || (nanos != 0 && timeout == 0)){timeout++;}
* 是半毫秒以上的nanos才会使得timeout++
* 3、其他机制类似于wait(long timeout)毕竟调用的它
* @param timeout
* @param nanos
* @throws InterruptedException
*/
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);
}
/**
* 调用wait(0)
* @throws InterruptedException
*/
public final void wait() throws InterruptedException {
wait(0);
}
finalize()
- 垃圾回收机制相关
/**
* 垃圾回收机制相关,当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
* @throws Throwable
*/
protected void finalize() throws Throwable {
}