写这个系列的原因,其实网上已经有无数源码分析的文章了,多一篇不多,少一篇不少,但为什么还要写这部分文章呢?
于私,
其一,上班族已经很久没有打过完整的一整段有意义的话,算是锻炼个人的书写、总结能力,
其二,别人的代码永远是别人的,只有亲自做过才知道其中的滋味,
其三,若干年后如果博客园还在,也算是一段美好的回忆。
于公,网上有大部分的文章属于copy,虽然copy没问题,但是看多了会觉得千篇一律,而且少了很多技术细节,我打算写得详细一点,啰嗦一点,如果能让刚刚入门Java的同学有所收获,那就心满意足了。
首先贴上 Object.java 的代码。
package java.lang; public class Object { private static native void registerNatives(); static { registerNatives(); } /** 通过对象获得一个类的实例对象,通过Class<?>,可以获取这个类的构造方法、方法和属性等。*/ public final native Class<?> getClass(); /** 返回对象的hash code。主要用于switch 字符串, hashMap等散列集。*/ public native int hashCode(); /** * 对比对象是否相等。最好和hashCode一起重写。 * 1.equals()对比对象值是否相同 * 2.== 对比两个对象引用是否一致,是否为同一个对象 */ public boolean equals(Object obj) { return (this == obj); } /** 复制一个对象。类要使用该方法,需要实现Cloneable接口。*/ protected native Object clone() throws CloneNotSupportedException; /** 转化为String时自动调用的方法,主要用于打印到控制台或日志文件,默认为类名@加十六进制的哈希值(基本不可读),最好重写。*/ public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } /** 同步相关代码等之后的Java随谈中详细介绍*/ 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 { 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); } public final void wait() throws InterruptedException { wait(0); } /** 向垃圾回收器“报告”回收该对象,可以通过重写这个方法实现来检测垃圾回收的时机。*/ protected void finalize() throws Throwable { } }
这里面每一个方法都十分重要,但有几个方法在很多时候都需要重写。我们先着重讲解下面这几个:
一、equals()和hashCode()
不重写equals比较的是对象是否为同一对象。不重写hashCode()会影响Map、Set的操作。
如何重写?
- 在之前的Java版本需要手动重写这两个方法。
- 如果你使用的是Java7以上的版本,可以使用Objects.deepEquals(Object a, Object b)和Objects.hash(Object... values),方便地进行方法重写。
- 如果你依赖了Lombok,可以使用@EqualsAndHashCode。
二、toString()
在Java中,当要连接对象和字符串时,会自动调用对象的toString()方法,默认为 类名@16进制哈希值,最好重写,增加可读性。
Object a = new Object(); String s = a + " ,hello";
同样,如果你依赖了Lombok,可以使用@ToString。
相关阅读