JDK版本: 1.8java
最近想看看jdk源码提升下技术深度(比较闲),万物皆对象,虽然Object大多native方法但仍是很重要的。app
package java.lang; /** * Java中的始祖,万物皆Object * @since JDK1.0 */ public class Object { private static native void registerNatives(); static { // 保证在clinit()最早执行,从而调native方法 registerNatives(); } /** * 返回运行时的Class类文件,返回的是个泛型,运行时泛型会进行类型擦除,实际返回以自身为边界 * 例如 new HelloWorld().getClass() * 返回 Class<? extends HelloWorld> */ public final native Class<?> getClass(); /** * 返回一个hash code整数,主要用于集合类使用,例如HashMap * 屡次调用返回值必须同样,可是同一个应用执行了多份的时候,不保证多个执行中值相等 * 若是两个对象调equels方法返回ture,那么hash code值必定相等(因此重写equels方法必定要重写hashCode方法) * 若是两个对象调equels方法返回false,hash code值不必定不相等,可是咱们重写hashCode方法时,应该尽可能作到不等,从而减小hash碰撞 * 不一样虚拟机的实现不太同样,可是主要是根据对象的内存地址来计算的 */ public native int hashCode(); /** * 对于非空的对象进行逻辑上是否相等的比较,默认是比较的内存地址 * 再次强调哈哈,若是两个对象调equels方法返回ture,那么hash code值必定相等(因此重写equels方法必定要重写hashCode方法) * 四大特性(1)reflexive自反性(2)symmetric对称性(3)transitive传递性(4)consistent一致性 */ public boolean equals(Object obj) { return (this == obj); } /** * 返回一个当前对象的副本,通常须要知足以下性质: * x.clone() != x * x.clone().getClass() == x.getClass() * x.clone().equals(x) * 能够根据须要实现浅拷贝和深拷贝,通常是浅拷贝 * @throws CloneNotSupportedException Object没有实现Cloneable接口,自己是不能使用clone方法的,其子类调用clone方法会抛出此异常.只有实现了Cloneable才能正常使用 * @see java.lang.Cloneable */ protected native Object clone() throws CloneNotSupportedException; /** * 返回一个对象的字符串表示 * 建议全部类都重写这个方法,由于不直观 * 字符串内容,类名加上hash code转成16进制 */ public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } /** * 用于随机唤醒一个在对象等待池中的线程 * 被唤醒的线程不会马上拿到对象的监视器锁,而是和其余在线程共同竞争,拿到锁以后恢复到调用wait方法时的同步状态 * 同一时间只有一个线程能拿到监视器锁 * * @throws IllegalMonitorStateException 若是当前执行notify方法的线程没拿到对象的监视器锁 */ public final native void notify(); /** * 一次唤醒全部等待池中的线程,其余和notify方法同样 */ public final native void notifyAll(); /** * 持有对象监视器的线程能够执行awit方法把本身放入等待池中,而且放弃持有该对象的全部同步资源,不会放弃获取的其余对象的同步资源 * 有四种状况线程能够逃出等待池: * 其余线程调用notify方法 * 其余线程调用notifyAll方法 * 其余线程调用interrupts方法 * 超时时间到了 * 逃出等待池拿到锁以后恢复到调用wait方法时的同步状态 * 特别强调,若是由于interrupts逃出了等待池,不会马上抛出InterruptedException,须要等到线程拿到锁 * 因为偶尔会发生伪唤醒(没有调用notify或interrupts也没超时),因此咱们在编码时应该以下例: * synchronized (obj) { * while (<condition does not hold>) * obj.wait(timeout); * ... // Perform action appropriate to condition * } * @param timeout 在等待池中的最长等待时间,时间到了就出狱了,若是值为0,则无期徒刑等待保释 * @throws IllegalArgumentException 超时时间是负数 * @throws IllegalMonitorStateException 当前线程没有拿到监视器锁 * @throws InterruptedException 中断位为true */ public final native void wait(long timeout) throws InterruptedException; /** * 提供纳秒级别的等待控制,其余同wait(long timeout) * @param nanos 额外的纳秒时间 * 0-999999. * @throws IllegalArgumentException timeout是负数,nanos是负数或者大于999999. */ 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(long timeout)方法同样,只是没有超时时间 */ public final void wait() throws InterruptedException { wait(0); } /** * 当垃圾收集器判断此对象没有被任何引用,是垃圾对象了,由垃圾收集器执行此方法销毁对象,因此什么时候执行是不肯定的 * JVM保证垃圾收集器调用此方法时候,该对象的锁不被任何线程持有了 * finalize方法只会被执行一次,因此咱们能够重写此方法特定一些清除工做,或者给对象一次复活机会,可是不建议重写此方法 * @throws Throwable the {@code Exception} raised by this method * @see java.lang.ref.WeakReference * @see java.lang.ref.PhantomReference */ protected void finalize() throws Throwable { } }
public class ObjectCloneTest { /** * 不实现 Cloneable 接口 * * 输出: * Exception in thread "main" java.lang.CloneNotSupportedException: study.ObjectCloneTest$Obj * at java.lang.Object.clone(Native Method) * at study.ObjectCloneTest$Obj.main(ObjectCloneTest.java:24) */ private static class Obj { public static void main(String[] args) throws CloneNotSupportedException { Obj o1 = new Obj(); Object o2 = o1.clone(); } } /** * 实现 Cloneable 接口,从结果看出默认实现是浅拷贝 * * 输出: * 两个对象地址相同么 * false * 两个对象的属性地址相同么 * true * 改变其中一个属性会变么? * [1, 2] * [1, 2] */ private static class ObjShallowCopy implements Cloneable { private List<String> list = new ArrayList<>(); @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { ObjShallowCopy o1 = new ObjShallowCopy(); o1.list.add("1"); ObjShallowCopy o2 = (ObjShallowCopy) o1.clone(); System.out.println("两个对象地址相同么"); System.out.println(o1 == o2); System.out.println("两个对象的属性地址相同么"); System.out.println(o1.list == o2.list); System.out.println("改变其中一个属性会变么?"); o2.list.add("2"); System.out.println(o1.list.toString()); System.out.println(o2.list.toString()); } } /** * 实现 Cloneable 接口,比较笨拙的作了一层深拷贝,只为了演示,深拷贝也能够经过序列号等方式实现 * * 输出: * 两个对象地址相同么 * false * 两个对象的属性地址相同么 * false * 改变其中一个属性会变么? * [1] * [1, 2] */ private static class ObjDeepCopy implements Cloneable { private List<String> list = new ArrayList<>(); @Override protected Object clone() throws CloneNotSupportedException { ObjDeepCopy obj = (ObjDeepCopy) super.clone(); List<String> list = new ArrayList<>(obj.list.size()); list.addAll(obj.list); obj.list = list; return obj; } public static void main(String[] args) throws CloneNotSupportedException { ObjDeepCopy o1 = new ObjDeepCopy(); o1.list.add("1"); ObjDeepCopy o2 = (ObjDeepCopy) o1.clone(); System.out.println("两个对象地址相同么"); System.out.println(o1 == o2); System.out.println("两个对象的属性地址相同么"); System.out.println(o1.list == o2.list); System.out.println("改变其中一个属性会变么?"); o2.list.add("2"); System.out.println(o1.list.toString()); System.out.println(o2.list.toString()); } } }
public class ObjectWaitNotifyTest { private volatile boolean flag = true; public static void main(String[] args) { ObjectWaitNotifyTest obj = new ObjectWaitNotifyTest(); new Thread(() -> { synchronized (obj) { System.out.println("绝食!"); while (obj.flag == true) { try { obj.wait(); System.out.println("真香!"); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); new Thread(() -> { synchronized (obj) { obj.flag = false; obj.notify(); System.out.println("海底捞走起!"); } }).start(); /** * 输出: * 绝食! * 海底捞走起! * 真香! */ } }