前几天支付宝电话面试,问了很多java底层的逻辑,心态炸了
本来只想以后背背面经算了,但是总觉得是对自己的不负责任,所以打算写系列文章,剖析java中常见对象,数据结构的底层逻辑
作为第一篇,那当然是对象之父——object了!
源码
package sourceCode;
/**
* @Author cs
* @date 22:55 2019/3/21
* @description:
*/
public class Object {
private static native void registerNatives();
//静态块注册,类的实例还没创建就会运行
static {
registerNatives();
}
public final native Class<?>getClass();
public native int hashCode();
public boolean equals(Object obj){
return (this==obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout,int nanos) throws InterruptedException{}
public final void wait() throws InterruptedException{
wait(0);
}
protected void finalize() throws Throwable{}
}
几个容易记不清作用的关键字,简单介绍下
关键字 | 作用 |
---|---|
protected | 保护,除本包类外,额外允许子类访问此方法 |
native | 其他语言实现的方法 |
final | 不可继承,不可重写,不可更改,对于对象限制的是引用 |
//先看equals方法,有趣的是这个equals本质是==,所以继承Object类的对象都会重写equals方法
public boolean equals(Object obj){
return (this==obj);
}
比如String的,
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
实现方法:
目标 | 方法 |
---|---|
同一个对象? | == |
对方是String对象? | instance |
长度一致? | value |
逐个字符比较 | char 数组 |
//返回一个对象的运行时类对象,就是调用这个方***输出 class 包名.类名
注意是运行时,所以运行子类返回子类,运行父类返回父类
public final native Class<?>getClass();
//hashcode就是求这个对象的散列值,以后会详细讲解
//一般重写equals方法,都要重写这个方法,因为equals相同,hashCode一定相同,为了保持这个原则,比如String 类也同时重写了hashCode方法
public native int hashCode();
//其他语言实现的的clone方法,还要抛出异常
protected native Object clone() throws CloneNotSupportedException;
clone是浅拷贝
浅拷贝与深拷贝的区别
所以clone出来的对象虽然是新对象,有新的地址,但是原对象内部的对象改变后,clone对象内部的对象依旧会变化
可以简单理解为原来是用电脑登qq,clone之后变成了手机登,但是两者qq上的消息还是同步的,一方变,另一方跟着变
//至今依旧记得我说了这个方法后,面试官说:“这是最不重要的方法” 难受
public String toString(){
return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
//这是多线程之间的通信方法 wait可使线程等待,而notify,notifyAll可以唤醒线程,剖析线程源码的时候再讲咯(其实是因为我也不太清楚哈哈~)
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout,int nanos) throws InterruptedException{}
public final void wait() throws InterruptedException{
wait(0);
}
//垃圾回收方法,一般jvm自动调用,以后再说啦
protected void finalize() throws Throwable{}