前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >java.util.Objects[源码解读]

java.util.Objects[源码解读]

作者头像
小诸葛
发布2020-04-14 15:54:23
5910
发布2020-04-14 15:54:23
举报
文章被收录于专栏:方法论方法论

简介:

Objects是自jdk1.7起新增的工具类,这个类由一些实用的静态方法组成,这些方法可以方便我们平时的开发,例如对象比较、获取对象的hash码等。

源码解读:

1.类及构造方法

代码语言:javascript
复制
/**
 * This class consists of {@code static} utility methods for operating
 * on objects.  These utilities include {@code null}-safe or {@code
 * null}-tolerant methods for computing the hash code of an object,
 * returning a string for an object, and comparing two objects.
 *
 * @since 1.7
 */
public final class Objects {
    private Objects() {
        throw new AssertionError("No java.util.Objects instances for you!");
    }
    
    ...
    
}

此类是由final修饰的,也就是不可以有子类,并且构造方法由private修饰,说明此类不可以被实例化(因为这个类的方法都是静态方法,当然就没有实例化的必要了)。

2.equals(Object a, Object b)

代码语言:javascript
复制
/**
     * Returns {@code true} if the arguments are equal to each other
     * and {@code false} otherwise.
     * Consequently, if both arguments are {@code null}, {@code true}
     * is returned and if exactly one argument is {@code null}, {@code
     * false} is returned.  Otherwise, equality is determined by using
     * the {@link Object#equals equals} method of the first
     * argument.
     *
     * @param a an object
     * @param b an object to be compared with {@code a} for equality
     * @return {@code true} if the arguments are equal to each other
     * and {@code false} otherwise
     * @see Object#equals(Object)
     */
    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

此方法用来比较两个对象是否相等,如果相等返回true,否则返回false。在进行比较时,首先会判断a和b是否是同一对象或者两个对象都为null(a == b),如果是,返回true,注意这个判断:a == b,这个比较其实包含了两种情况,情况1:a和b为同一对象(对象引用地址相同),情况2:a和b均为null(当a和b均为null时,a == b)。当a不为null时,调用a的equals方法进行比较,最后返回比较结果。

3.deepEquals(Object a, Object b)

代码语言:javascript
复制
/**
    * Returns {@code true} if the arguments are deeply equal to each other
    * and {@code false} otherwise.
    *
    * Two {@code null} values are deeply equal.  If both arguments are
    * arrays, the algorithm in {@link Arrays#deepEquals(Object[],
    * Object[]) Arrays.deepEquals} is used to determine equality.
    * Otherwise, equality is determined by using the {@link
    * Object#equals equals} method of the first argument.
    *
    * @param a an object
    * @param b an object to be compared with {@code a} for deep equality
    * @return {@code true} if the arguments are deeply equal to each other
    * and {@code false} otherwise
    * @see Arrays#deepEquals(Object[], Object[])
    * @see Objects#equals(Object, Object)
    */
    public static boolean deepEquals(Object a, Object b) {
        if (a == b)
            return true;
        else if (a == null || b == null)
            return false;
        else
            return Arrays.deepEquals0(a, b);
    }

此方法判断两个对象是否“真的(deeply)”相等,怎么理解这个“真的”呢?这么说吧,equals方法是判断两个对象是否相等的,但是如果是内部元素相等的两个不同数组,通过equals方法是判断不出来的,看下面的例子:

代码语言:javascript
复制
@Test
    public void test1(){
        int[] ary1 = {1,2,3};
        int[] ary2 = {1,2,3};

        boolean res1 = Objects.equals(ary1,ary2);
        boolean res2 = Objects.deepEquals(ary1,ary2);

        System.out.println("res1:" + res1);
        System.out.println("res2:" + res2);
    }

输出结果:

代码语言:javascript
复制
res1:false
res2:true

可以看到,数组ary1和ary2两个数组内部元素都是相等的,但是通过equals方法判断结果是false,至于原因,就是equals方法的局限性决定的(方法2中已做说明)。但是,通过deepEquals方法就得出了正确的判断结果,这是因为deepEquals方法对参数为数组的情况做了判断,此判断是调用了Arrays的deepEquals0方法进行判断,这个deepEquals0方法就对元素为数组的情况做了判断。

所以,这个“真的(deeply)”可以这么理解:当元素为对象时,判断这两个对象是否相等,当元素为对象数组时,判断数组内部元素是否一一相等,并返回最终判断结果。

4.hashCode(Object o)

代码语言:javascript
复制
/**
     * Returns the hash code of a non-{@code null} argument and 0 for
     * a {@code null} argument.
     *
     * @param o an object
     * @return the hash code of a non-{@code null} argument and 0 for
     * a {@code null} argument
     * @see Object#hashCode
     */
    public static int hashCode(Object o) {
        return o != null ? o.hashCode() : 0;
    }

此方法返回一个对象的hash码,如果参数为null,则返回0。

5.hash(Object... values)

代码语言:javascript
复制
/**
    * Generates a hash code for a sequence of input values. The hash
    * code is generated as if all the input values were placed into an
    * array, and that array were hashed by calling {@link
    * Arrays#hashCode(Object[])}.
    *
    * <p>This method is useful for implementing {@link
    * Object#hashCode()} on objects containing multiple fields. For
    * example, if an object that has three fields, {@code x}, {@code
    * y}, and {@code z}, one could write:
    *
    * <blockquote><pre>
    * &#064;Override public int hashCode() {
    *     return Objects.hash(x, y, z);
    * }
    * </pre></blockquote>
    *
    * <b>Warning: When a single object reference is supplied, the returned
    * value does not equal the hash code of that object reference.</b> This
    * value can be computed by calling {@link #hashCode(Object)}.
    *
    * @param values the values to be hashed
    * @return a hash value of the sequence of input values
    * @see Arrays#hashCode(Object[])
    * @see List#hashCode
    */
    public static int hash(Object... values) {
        return Arrays.hashCode(values);
    }

此方法返回多个对象的hash码,在覆写hashCode方法时,如果需要生成含有多个参数的hash码,就可以调用此方法。需要注意的是:如果只有一个参数,调用此方法和调用hashCode方法生成的hash码并不相等。

6.toString(Object o)

代码语言:javascript
复制
/**
     * Returns the result of calling {@code toString} for a non-{@code
     * null} argument and {@code "null"} for a {@code null} argument.
     *
     * @param o an object
     * @return the result of calling {@code toString} for a non-{@code
     * null} argument and {@code "null"} for a {@code null} argument
     * @see Object#toString
     * @see String#valueOf(Object)
     */
    public static String toString(Object o) {
        return String.valueOf(o);
    }

此方法将一个对象转为String字符串并返回(内部就是调用String的valueOf方法),如果对象为null则返回“null”。

7.toString(Object o, String nullDefault)

代码语言:javascript
复制
/**
     * Returns the result of calling {@code toString} on the first
     * argument if the first argument is not {@code null} and returns
     * the second argument otherwise.
     *
     * @param o an object
     * @param nullDefault string to return if the first argument is
     *        {@code null}
     * @return the result of calling {@code toString} on the first
     * argument if it is not {@code null} and the second argument
     * otherwise.
     * @see Objects#toString(Object)
     */
    public static String toString(Object o, String nullDefault) {
        return (o != null) ? o.toString() : nullDefault;
    }

此方法同equals,不过当参数为null时,返回的参数可以自定义。

8.compare(T a, T b, Comparator<? super T> c)

代码语言:javascript
复制
/**
     * Returns 0 if the arguments are identical and {@code
     * c.compare(a, b)} otherwise.
     * Consequently, if both arguments are {@code null} 0
     * is returned.
     *
     * <p>Note that if one of the arguments is {@code null}, a {@code
     * NullPointerException} may or may not be thrown depending on
     * what ordering policy, if any, the {@link Comparator Comparator}
     * chooses to have for {@code null} values.
     *
     * @param <T> the type of the objects being compared
     * @param a an object
     * @param b an object to be compared with {@code a}
     * @param c the {@code Comparator} to compare the first two arguments
     * @return 0 if the arguments are identical and {@code
     * c.compare(a, b)} otherwise.
     * @see Comparable
     * @see Comparator
     */
    public static <T> int compare(T a, T b, Comparator<? super T> c) {
        return (a == b) ? 0 :  c.compare(a, b);
    }

此方法返回两个对象的比较结果,如果这两个对象完全相同,则返回0,否则,调用传入的比较器(Comparator)进行比较,并返回比较结果。

9.requireNonNull(T obj)

代码语言:javascript
复制
/**
     * Checks that the specified object reference is not {@code null}. This
     * method is designed primarily for doing parameter validation in methods
     * and constructors, as demonstrated below:
     * <blockquote><pre>
     * public Foo(Bar bar) {
     *     this.bar = Objects.requireNonNull(bar);
     * }
     * </pre></blockquote>
     *
     * @param obj the object reference to check for nullity
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

此方法判断一个对象是否为null,当为null时,抛出NullPointerException,否则返回该对象。

10.requireNonNull(T obj, String message)

代码语言:javascript
复制
/**
     * Checks that the specified object reference is not {@code null} and
     * throws a customized {@link NullPointerException} if it is. This method
     * is designed primarily for doing parameter validation in methods and
     * constructors with multiple parameters, as demonstrated below:
     * <blockquote><pre>
     * public Foo(Bar bar, Baz baz) {
     *     this.bar = Objects.requireNonNull(bar, "bar must not be null");
     *     this.baz = Objects.requireNonNull(baz, "baz must not be null");
     * }
     * </pre></blockquote>
     *
     * @param obj     the object reference to check for nullity
     * @param message detail message to be used in the event that a {@code
     *                NullPointerException} is thrown
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNonNull(T obj, String message) {
        if (obj == null)
            throw new NullPointerException(message);
        return obj;
    }

此方法同方法9,只是抛出NullPointerException时,可以传入自定义的字符串。

11.isNull(Object obj)

代码语言:javascript
复制
/**
     * Returns {@code true} if the provided reference is {@code null} otherwise
     * returns {@code false}.
     *
     * @apiNote This method exists to be used as a
     * {@link java.util.function.Predicate}, {@code filter(Objects::isNull)}
     *
     * @param obj a reference to be checked against {@code null}
     * @return {@code true} if the provided reference is {@code null} otherwise
     * {@code false}
     *
     * @see java.util.function.Predicate
     * @since 1.8
     */
    public static boolean isNull(Object obj) {
        return obj == null;
    }

此方法返回一个对象==null的结果。

12.nonNull(Object obj)

代码语言:javascript
复制
/**
     * Returns {@code true} if the provided reference is non-{@code null}
     * otherwise returns {@code false}.
     *
     * @apiNote This method exists to be used as a
     * {@link java.util.function.Predicate}, {@code filter(Objects::nonNull)}
     *
     * @param obj a reference to be checked against {@code null}
     * @return {@code true} if the provided reference is non-{@code null}
     * otherwise {@code false}
     *
     * @see java.util.function.Predicate
     * @since 1.8
     */
    public static boolean nonNull(Object obj) {
        return obj != null;
    }

此方法返回一个对象!=null的结果。

13.requireNonNull(T obj, Supplier<String> messageSupplier)

代码语言:javascript
复制
/**
     * Checks that the specified object reference is not {@code null} and
     * throws a customized {@link NullPointerException} if it is.
     *
     * <p>Unlike the method {@link #requireNonNull(Object, String)},
     * this method allows creation of the message to be deferred until
     * after the null check is made. While this may confer a
     * performance advantage in the non-null case, when deciding to
     * call this method care should be taken that the costs of
     * creating the message supplier are less than the cost of just
     * creating the string message directly.
     *
     * @param obj     the object reference to check for nullity
     * @param messageSupplier supplier of the detail message to be
     * used in the event that a {@code NullPointerException} is thrown
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     * @since 1.8
     */
    public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
        if (obj == null)
            throw new NullPointerException(messageSupplier.get());
        return obj;
    }

此方法对传入的参数进行判断,当传入的参数为null时,抛出NullPointerException,并且可传入自定义的字符串(此方法通过传入一个结果提供类Supplier提供字符串)。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小诸葛的博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介:
  • 源码解读:
    • 1.类及构造方法
      • 4.hashCode(Object o)
        • 6.toString(Object o)
          • 7.toString(Object o, String nullDefault)
            • 8.compare(T a, T b, Comparator<? super T> c)
              • 9.requireNonNull(T obj)
                • 10.requireNonNull(T obj, String message)
                  • 11.isNull(Object obj)
                    • 12.nonNull(Object obj)
                      • 13.requireNonNull(T obj, Supplier<String> messageSupplier)
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档