zoukankan      html  css  js  c++  java
  • Object

    Java 是一门纯面向对象的编程语言,Java 世界里万物皆对象,这些对象的祖宗就是 Object 类了。学习其他类实现的过程中,难免与 Object 打交道,所以这里记录下学习过程中的笔记吧!

    First Blood

    首先是在学习 HashMap、HashTable 的过程中遇到了关于 Object 类的 hashCode 和 equals 这两方法的讨论,那就去看看 JDK 源码里是怎么描述这两个方法的吧:

    /**
         * Returns a hash code value for the object. This method is
         * supported for the benefit of hash tables such as those provided by
         * {@link java.util.HashMap}.
         * <p>
         * The general contract of {@code hashCode} is:
         * <ul>
         * <li>Whenever it is invoked on the same object more than once during
         *     an execution of a Java application, the {@code hashCode} method
         *     must consistently return the same integer, provided no information
         *     used in {@code equals} comparisons on the object is modified.
         *     This integer need not remain consistent from one execution of an
         *     application to another execution of the same application.
         * <li>If two objects are equal according to the {@code equals(Object)}
         *     method, then calling the {@code hashCode} method on each of
         *     the two objects must produce the same integer result.
         * <li>It is <em>not</em> required that if two objects are unequal
         *     according to the {@link java.lang.Object#equals(java.lang.Object)}
         *     method, then calling the {@code hashCode} method on each of the
         *     two objects must produce distinct integer results.  However, the
         *     programmer should be aware that producing distinct integer results
         *     for unequal objects may improve the performance of hash tables.
         * </ul>
         * <p>
         * As much as is reasonably practical, the hashCode method defined by
         * class {@code Object} does return distinct integers for distinct
         * objects. (This is typically implemented by converting the internal
         * address of the object into an integer, but this implementation
         * technique is not required by the
         * Java&trade; programming language.)
         *
         * @return  a hash code value for this object.
         * @see     java.lang.Object#equals(java.lang.Object)
         * @see     java.lang.System#identityHashCode
         */
        public native int hashCode();
    

    注释里先说了 hashCode 方法就是服务于哈希表数据结构类(比如 HashMap),该方法是 JDK 原生方法,具体实现可能随着 JDK 厂商版本不同而不同,所以我们就不去看其具体实现了,就只说说其一般约定吧:

    1. 在同一次运行中的 JVM 里,同一个对象的 hashCode 方法返回值应当一致;不时同一次运行的时,该方法返回值可以不一致;
    2. 如果两个对象通过 equals 方法判等时结果返回真,那么这两个对象调用 hashCode 方法的返回值应该一致;
    3. 两个不同对象调用 hashCode 方法并不强制其返回结果必须不一致,但是其返回结果不一致时哈希表的性能更高;
    4. JDK 实现里,鉴于实用原则,不同对象的 hashCode 方法返回值确实是不一致的(实现原理大致就是将该对象的内存地址做一些处理后返回),但是这一点在《Java 编程规范》中并未做强制要求;

    然后再说 equals 方法:

    /**
         * Indicates whether some other object is "equal to" this one.
         * <p>
         * The {@code equals} method implements an equivalence relation
         * on non-null object references:
         * <ul>
         * <li>It is <i>reflexive</i>: for any non-null reference value
         *     {@code x}, {@code x.equals(x)} should return
         *     {@code true}.
         * <li>It is <i>symmetric</i>: for any non-null reference values
         *     {@code x} and {@code y}, {@code x.equals(y)}
         *     should return {@code true} if and only if
         *     {@code y.equals(x)} returns {@code true}.
         * <li>It is <i>transitive</i>: for any non-null reference values
         *     {@code x}, {@code y}, and {@code z}, if
         *     {@code x.equals(y)} returns {@code true} and
         *     {@code y.equals(z)} returns {@code true}, then
         *     {@code x.equals(z)} should return {@code true}.
         * <li>It is <i>consistent</i>: for any non-null reference values
         *     {@code x} and {@code y}, multiple invocations of
         *     {@code x.equals(y)} consistently return {@code true}
         *     or consistently return {@code false}, provided no
         *     information used in {@code equals} comparisons on the
         *     objects is modified.
         * <li>For any non-null reference value {@code x},
         *     {@code x.equals(null)} should return {@code false}.
         * </ul>
         * <p>
         * The {@code equals} method for class {@code Object} implements
         * the most discriminating possible equivalence relation on objects;
         * that is, for any non-null reference values {@code x} and
         * {@code y}, this method returns {@code true} if and only
         * if {@code x} and {@code y} refer to the same object
         * ({@code x == y} has the value {@code true}).
         * <p>
         * 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.
         *
         * @param   obj   the reference object with which to compare.
         * @return  {@code true} if this object is the same as the obj
         *          argument; {@code false} otherwise.
         * @see     #hashCode()
         * @see     java.util.HashMap
         */
        public boolean equals(Object obj) {
            return (this == obj);
        }
    

    可以看到该方法的实现是用双等号做判等校验的,这样其实就是比较两个对象的内存地址。该方法有一些特性:

    1. 自反省
    2. 对象性
    3. 传递性
    4. 一致性

    熟悉的感觉,好像那个高中数学公理也有这样的特性。
    该方法的参数可以是 null,由此看见:在 Java 中 null 虽非对象,却是可以作为对象实例的值;
    还有一点要注意:覆写 equals 方法后要记得覆写 hashCode 方法,以维持 hashCode 方法的第二个约定:如果两个对象通过 equals 方法判等时结果返回真,那么这两个对象调用 hashCode 方法的返回值应该一致;

    Double Kill

    熟悉了上面的 hashCode 方法和 equals 方法的作用,那么再看 toString 方法就易如反掌了:

    /**
         * Returns a string representation of the object. In general, the
         * {@code toString} method returns a string that
         * "textually represents" this object. The result should
         * be a concise but informative representation that is easy for a
         * person to read.
         * It is recommended that all subclasses override this method.
         * <p>
         * The {@code toString} method for class {@code Object}
         * returns a string consisting of the name of the class of which the
         * object is an instance, the at-sign character `{@code @}', and
         * the unsigned hexadecimal representation of the hash code of the
         * object. In other words, this method returns a string equal to the
         * value of:
         * <blockquote>
         * <pre>
         * getClass().getName() + '@' + Integer.toHexString(hashCode())
         * </pre></blockquote>
         *
         * @return  a string representation of the object.
         */
        public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
    

    为了人类的可读性,toString 方法把 hashCode 方法返回的整数类型转换为了十六进制字符串类型。

    参考

    1. https://www.cnblogs.com/ttylinux/p/6539436.html
  • 相关阅读:
    使用JDBC连接MySql时出现:The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration
    Mysql Lost connection to MySQL server at ‘reading initial communication packet', system error: 0
    mysql-基本命令
    C# 监听值的变化
    DataGrid样式
    C# 获取当前日期时间
    C# 中生成随机数
    递归和迭代
    PHP 时间转几分几秒
    PHP 根据整数ID,生成唯一字符串
  • 原文地址:https://www.cnblogs.com/optor/p/8461616.html
Copyright © 2011-2022 走看看