Java中Objects类的方法们
Object类的声明与构造函数
public final class Objects{
private Objects(){
throw new AssertionError("No java.util.Objects instances for you!");
}
}
首先,Objects的声明是public和final的,这意味着所有代码都可以直接访问Objects的静态方法,但是不能够直接的显式继承Objects类。实际上,通过阅读下面的源码,我发现Objects类更像是一个提供大量作用于对象与对象间方法的源码库,通过这一系列的static方法,解决了对象与对象之间的关系以及对象的表示等问题。
其次,Objects的构造方法是private的,通常的private构造方法出现在单例模式中,但是后面的代码段中并没有出现与常规单例模式所对应的private static的Objects对象,因此,开发者这样写的目的就是不允许用户自己声明Object类,构造方法中唯一一行代码便是抛出异常也应证了这个想法。
“No java.util.Objects instances for you!”Objects不是给你小子用的!
equals:两个对象的相等
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
equals是一个static的方法,返回的值是两个函数是否相等的真值。满足真值需要两个条件之一:
1.两个变量引用了相同的对象
2.如果a非空,则通过其equals(b)方法返回判定值。
这里需要额外提一点,就是a中的equals可能被重写,可能会出现即便b是null,也还是返回true的情况。
deepEquals方法
deepEquals主要针对数组对象。
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);
}
Arrays.deepEquals0(a, b)方法实际上就是依次检查数组中所有对象是否都equals,实际上,通过调用deepEquals,这一方法同样适用于多维数组。
hashCode与hash
这两个方法就是分别针对单个Object与多个Object对象来获取哈希码的。项目上刚好涉及到HashTable,HashSet这些数据结构,过几天把这些研究明白,重新写好了再另发一篇博客。
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
toString方法
java里面定义了两个toString方法:
public static String toString(Object o) {
return String.valueOf(o);
}
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
这个方法与Python中的__str__类似,都是将一个对象转换为字符串这种人能直接接受的信号,毕竟,所有程序归根到底,都是为人服务的,也离不开人能接收到的信息,最简单也最实惠的方式就是字符串。
第二个重载方法是当对象为空时,返回一个默认的字符串nullDefault。否则遇到空字符串的时候直接返回 “null”。
compare 比较
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
调用对象c的比较方法,返回a与b的比较值。当然a与b指向一个对象时就默认相等。
requireNonNull
检查输入的指针是否为null。
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
重载方法相当于之前toString中的重载方法,不同的是这次的默认字符串用于抛出异常。
isNull与nonNull
孪生兄弟,不解释。
public static boolean isNull(Object obj) {
return obj == null;
}
public static boolean nonNull(Object obj) {
return obj != null;
}
requireNonNull系列
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier == null ?
null : messageSupplier.get());
return obj;
}
public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier) {
return (obj != null) ? obj : requireNonNull(requireNonNull(supplier, "supplier").get(), "supplier.get()");
}
这里,把源码中的出现顺序稍微改了一下。requireNonNull就相当于是一个检查是否为null的过滤器,如果为null则抛出异常,反之返回原对象。
requireNonNullElse把上一个方法升级了,如果当前对象是null,则让defaultObj替补上去,看看此对象是否为空。
第三个则是反复嵌套两次。
Index相关
@ForceInline
public static int checkIndex(int index, int length) {
return Preconditions.checkIndex(index, length, null);
}
public static int checkFromToIndex(int fromIndex, int toIndex, int length) {
return Preconditions.checkFromToIndex(fromIndex, toIndex, length, null);
}
public static int checkFromIndexSize(int fromIndex, int size, int length) {
return Preconditions.checkFromIndexSize(fromIndex, size, length, null);
}
主要查看是否出现数组访问越界的情况。
下一篇: 详解C#泛型的类型参数约束