zoukankan      html  css  js  c++  java
  • Java源码赏析(一)Object 类


    写这个系列的原因,其实网上已经有无数源码分析的文章了,多一篇不多,少一篇不少,但为什么还要写这部分文章呢?
    于私,
    其一,上班族已经很久没有打过完整的一整段有意义的话,算是锻炼个人的书写、总结能力,
    其二,别人的代码永远是别人的,只有亲自做过才知道其中的滋味,
    其三,若干年后如果博客园还在,也算是一段美好的回忆。
    于公,网上有大部分的文章属于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的操作。

    如何重写?

    1. 在之前的Java版本需要手动重写这两个方法。
    2. 如果你使用的是Java7以上的版本,可以使用Objects.deepEquals(Object a, Object b)和Objects.hash(Object... values),方便地进行方法重写。
    3. 如果你依赖了Lombok,可以使用@EqualsAndHashCode。

      

    二、toString()

    在Java中,当要连接对象和字符串时,会自动调用对象的toString()方法,默认为 类名@16进制哈希值,最好重写,增加可读性。

    Object a = new Object();
    String s = a + " ,hello";

    同样,如果你依赖了Lombok,可以使用@ToString。

    相关阅读

    1. ORACLE JAVA 教程 Object

  • 相关阅读:
    初赛—算法复杂度
    2-SAT
    最小生成树
    18-短信验证码接口
    17-腾讯云短信开发
    16-手机号是否存在验证接口
    15-多方式登录
    14-登录注册页面
    13-Git
    12-跨域请求详解
  • 原文地址:https://www.cnblogs.com/kwanwoo/p/13591195.html
Copyright © 2011-2022 走看看