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類中定義的一些方法。

相關文章
相關標籤/搜索