Objects类

1.概况

Object是Java类库中的一个特殊类,也是全部类的父类。也就是说Java容许把任何类型的对象赋给Object类型的变量。当一个类被定义后,若是没有指定继承的父类,那么默认父类就是Object类。Objects包含Object类的静态实用程序方法,是JDK1.7版本添加的一个工具类,用于操做对象或者在操做前检查某些条件。这些实用程序包括null或null方法,用于计算对象的哈希代码,返回对象的字符串,比较两个对象,以及检查索引或子范围值是否超出范围。 java

2.Objects类的定义

public final class Objects {...}

未标注继承与实现,可是默认继承Object类。数组

3.Object类的方法

3.1 public static < T > int compare(T a, T b, Comparator<? super T> c)

此方法用于比较a,b两个对象若是a,b两个对象指向同一引用地址,返回0;不然调用c的compare方法进行比较,cd的compare方法中传入的两个参数就分别是a,b。 源代码:ide

public static <T> int compare(T a, T b, Comparator<? super T> c) {
   return (a == b) ? 0 :  c.compare(a, b);
}

测试代码:函数

public class Demo1 implements Comparator<Demo1> {
   private String data;

   public Demo1() {
  }

   public Demo1(String data) {
       this.data = data;
  }

   public static void main(String[] args) {
       Demo1 test1 = new Demo1("测试代码Test1");
       Demo1 test2 = new Demo1("测试代码Test2");
       Demo1 test3 = new Demo1("测试代码Test1");
       int a = Objects.compare(test1, test1, new Demo1());
       System.out.println(a);
       int b = Objects.compare(test1, test3, new Demo1());
       System.out.println(b);
       int c = Objects.compare(test1, test2, new Demo1());
       System.out.println(c);
  }

   @Override
   public int compare(Demo1 o1, Demo1 o2) {
       if (o1.data == o2.data)
           return 1;
       return 2;
  }
}

/*
输出:
0
1
2
*/
3.2 public static boolean deepEquals(Object a, Object b)

此方法用于比较a,b两个对象是否深度相等,为何要叫深度相等?由于a,b两个对象均可觉得数组。因为Java中Object类是一切类的基类,因此Object o = new Object[10]的代码是被容许的。因此传入的对象能够是一个数组。若是传入的对象是数组,要比较两个对象是否深度相等,就要比较两个数组对应下标的元素是否都相等。若是传入的对象有一个不是数组,就直接调用a对象的equals方法传入b对象比较两对象是否相等。 下面咱们来看下源码:工具

public static boolean deepEquals(Object a, Object b) {
   //若是a和b指向同一地址,则a和b是同一对象,返回true。
   if (a == b)
       return true;
   //若是a或b中有一对象为空,则a和b不是同一类型对象,返回false。这样也避免了当a为空或者b为空时调用equals方法形成的空指针引用异常。
   else if (a == null || b == null)
       return false;
   //不然,调用Arrays类的deepEquals0方法对a,b进行深度比较。
   else
       return Arrays.deepEquals0(a, b);
}

咱们跳到Arrays类的deepEquals0方法进行分析,虽然有不少的判断语句,可是逻辑基本相同,咱们就分析其中几个:性能

static boolean deepEquals0(Object e1, Object e2) {
   //由于以后要调用e1的equals方法,因此e1不能为空。
   assert e1 != null;
   //定义返回值。
   boolean eq;
   //这个if是用于判断引用数据类型数组的,若是e1,e2都是引用数据类型数组的话,就调用Arrays类的deepEquals方法判断两数组是否相等。以后的基本数据类型的判断流程也同样。
   if (e1 instanceof Object[] && e2 instanceof Object[])
       eq = deepEquals ((Object[]) e1, (Object[]) e2);
   else if (e1 instanceof byte[] && e2 instanceof byte[])
       eq = equals((byte[]) e1, (byte[]) e2);
   else if (e1 instanceof short[] && e2 instanceof short[])
       eq = equals((short[]) e1, (short[]) e2);
   else if (e1 instanceof int[] && e2 instanceof int[])
       eq = equals((int[]) e1, (int[]) e2);
   else if (e1 instanceof long[] && e2 instanceof long[])
       eq = equals((long[]) e1, (long[]) e2);
   else if (e1 instanceof char[] && e2 instanceof char[])
       eq = equals((char[]) e1, (char[]) e2);
   else if (e1 instanceof float[] && e2 instanceof float[])
       eq = equals((float[]) e1, (float[]) e2);
   else if (e1 instanceof double[] && e2 instanceof double[])
       eq = equals((double[]) e1, (double[]) e2);
   else if (e1 instanceof boolean[] && e2 instanceof boolean[])
       eq = equals((boolean[]) e1, (boolean[]) e2);
   //若是e1和e2不全为数组,就调用e1的equals方法。
   else
       eq = e1.equals(e2);
   //返回判断的结果。
   return eq;
}

Arrays类的deepEquals方法测试

public static boolean deepEquals(Object[] a1, Object[] a2) {
   //若是传入的两数组指向同一地址,则是同一对象,返回true。
   if (a1 == a2)
       return true;
   //若是a1或a2中有一对象为空,则a1和a2不是同一类型对象,返回false。这样也避免了当a1为空或者a2为空时调用equals方法形成的空指针引用异常。
   if (a1 == null || a2==null)
       return false;
   int length = a1.length;
   //判断a1或a2的长度是否相等,不相等则显然不能比较,返回false。
   if (a2.length != length)
       return false;

   //循环遍历数组比较两数组中元素是否都相等。
   for (int i = 0; i < length; i++) {
       Object e1 = a1[i];
       Object e2 = a2[i];

       //地址相同,是同一对象,继续遍历。
       if (e1 == e2)
           continue;
       //e1为空,不是同一对象,返回false。
       if (e1 == null)
           return false;

       // Figure out whether the two elements are equal
       //再次对数组中e1,e2元素进行深度比较,而不是直接调用e1的equals方法,避免e1或e2仍是数组致使误判。
       boolean eq = deepEquals0(e1, e2);

       //若是e1与e2比较返回的是false,则a1,a2不相等,返回false。
       if (!eq)
           return false;
  }
   //比较完毕,没有不相等的元素,返回true。
   return true;
}

测试代码:ui

public static void main(String[] args) {
   Object[] o1 = {1, "String", 'c', 1.0, false};
   Object o11 = o1;
   Object[] o2 = {1, "String", 'c', 1.0, false};
   Object o22 = o2;
   Object[] o3 = {1, "String", 'c', 1.0, true};
   Object o33 = o3;
   System.out.println(Objects.deepEquals(o11, o11));
   System.out.println(Objects.deepEquals(o11, o22));
   System.out.println(Objects.deepEquals(o11, o33));
   Object[] o4 = {o11, o11};
   Object[] o5 = {o11, o22};
   Object[] o6 = {o11, o33};
   System.out.println(Objects.deepEquals(o4, o4));
   System.out.println(Objects.deepEquals(o4, o5));
   System.out.println(Objects.deepEquals(o4, o6));
}
3.3 public static boolean equals(Object a, Object b)

判断两对象是否相等,相比直接调用其中一对象的equals方法,a != null避免了空指针引用异常,相等返回true,不等返回false。 源代码:this

public static boolean equals(Object a, Object b) {
   return (a == b) || (a != null && a.equals(b));
}
3.4 public static int hash(Object... values)

获得一列对象的hashcode,使用了Arrays.hashCode(Object[])方法,Object[]数组元素就是hash方法传入的参数值,这里的values实际上是一个Object数组。Object... values的参数写法表示传入的Object对象不限制数量。 源代码:atom

public static int hash(Object... values) {
   return Arrays.hashCode(values);
}
3.5 public static int hashCode(Object o)

获取一个对象的hashCode。 源代码:

public static int hashCode(Object o) {
   return o != null ? o.hashCode() : 0;
}
3.6 public static boolean isNull(Object obj)

判断对象是否为空,为空返回true,不为空返回false。 源代码:

public static boolean isNull(Object obj) {
   return obj == null;
}
3.7 public static boolean nonNull(Object obj)

判断对象是否为不为空,不为空返回true,为空返回false。 源代码:

public static boolean nonNull(Object obj) {
   return obj != null;
}
3.8 private Objects()

私有的构造方法,必定抛出断言错误:“没有适合您的java.util.Objects实例!” 源代码:

private Objects() {
   throw new AssertionError("No java.util.Objects instances for you!");
}
3.9 public static <T> T requireNonNull(T obj)

检查指定的对象引用是否不是null,是null则抛出空指针异常,不然返回传入的对象。此方法主要用于在方法和构造函数中进行参数验证,以下所示:

public Foo(Bar bar) {
   this.bar = Objects.requireNonNull(bar);
}

源代码:

public static <T> T requireNonNull(T obj) {
   if (obj == null)
       throw new NullPointerException();
   return obj;
}
3.10 public static <T> T requireNonNull(T obj, String message)

检查指定的对象引用是否不是null,是null则抛出空指针异常并将第二个参数的字符串值写在异常信息中,不然返回传入的对象。此方法主要用于在方法和构造函数中进行参数验证,以下所示:

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");
}

源代码:

public static <T> T requireNonNull(T obj, String message) {
   if (obj == null)
       throw new NullPointerException(message);
   return obj;
}
3.11 public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier)

检查指定的对象引用是否为null ,若是是,则抛出自定义的NullPointerException。与方法requireNonNull(Object, String)不一样,此方法容许建立要延迟的消息,直到进行空检查。 虽然这能够在非空状况下赋予性能优点,但在决定调用此方法时,应注意建立消息提供者的成本小于仅直接建立字符串消息的成本。 源代码:

public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
   if (obj == null)
       throw new NullPointerException(messageSupplier.get());
   return obj;
}
3.12 public static String toString(Object o)

返回传入对象o的toString方法返回的字符串,若是传入对象为空,返回"null"字符串。 源代码:

public static String toString(Object o) {
   return String.valueOf(o);
}
3.13 public static String toString(Object o, String nullDefault)

若是传入对象非空,返回该对象的toString方法返回的字符串,不然返回自定义的信息。 源代码:

public static String toString(Object o, String nullDefault) {
   return (o != null) ? o.toString() : nullDefault;
}

以上就是Objects类中定义的一些方法。

相关文章
相关标签/搜索