一、前言
Objects是自jdk1.7起新增的工具类,这个类由一些实用的静态方法组成,这些方法可以方便我们平时的开发,例如对象比较、获取对象的hash码等。
二、源码解析
继承了哪些类
由上图可知Objects
没有继承的父类(除了Object
以外)或者实现的接口。
构造方法
/**
* 通过私有化构造器强化不可实例化的能力。
*/
private Objects() {
throw new AssertionError("No java.util.Objects instances for you!");
}
为什么Objects的构造方法是私有的?
参考枚举类为什么构造函数必须是私有的可以得知其中原因:
枚举被设计成是单例模式,即枚举类型会由JVM在加载的时候,实例化枚举对象,你在枚举类中定义了多少个就会实例化多少个,JVM为了保证每一个枚举类元素的唯一
实例,是不会允许外部进行new的,所以会把构造函数设计成private,防止用户生成实例,破坏唯一性。
枚举类型是单例模式的。你需要实例化一次,然后再整个程序之中就可以调用他的方法和成员变量了。枚举类型使用单例模式是因为他的值是固定的,不需要发生改变。
常用方法
/**
* equals方法比较两个对象是否相等
* 首先比较内存地址,然后比较a.equals(b),只要符合其中之一返回true
*
* @param a
* @param b
* @return
*/
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
/**
* 深度比较两个对象是否相等
* 首先比较内存地址,相同返回true;如果传入的是数组,则比较数组内的对应下标值是否相同
*
* @param a
* @param b
* @return
*/
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);
}
/**
* 返回对象的hash值,若参数的为null,返回0
*
* @param o
* @return
*/
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
/**
* 当传入多个参数转成数组,计算Hash值
* 所有的输入值都放在一个数组中,然后通过调用Arrays.hashCode(Object[])对该数组进行散列处理一样。
* 此方法对于在包含多个字段的对象上实现Object.hashCode()非常有用。
* <p>
* 例如,如果一个对象有三个字段x、y和z,可以这样写:
* public int hashCode() {
* return Objects.hash(x, y, z);
* }
*
* @param values
* @return
*/
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
/**
* 返回对非空参数调用toString的结果,对空参数则返回“null”。
*
* @param o
* @return
*/
public static String toString(Object o) {
return String.valueOf(o);
}
/**
* 如果第一个参数不为空,则返回对第一个参数调用toString的结果,否则返回第二个参数。
*
* @param o
* @param nullDefault
* @return
*/
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
/**
* 如果参数相同,则返回0,否则返回c.compare(a, b),如果两个参数都为null,则返回0。
*
* @param a
* @param b
* @param c
* @param <T>
* @return
*/
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
/**
* 检查指定的对象引用是否为空。
* 该方法主要用于方法和构造函数中的参数验证,例如:
* public Foo(Bar bar) {
* this.bar = Objects.requireNonNull(bar);
* }
*
* @param obj
* @param <T>
* @return
*/
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
/**
* 如果传入的参数为null就抛出NullPointerException并可以指定错误信息message,否者返回参数对象
*
* @param obj
* @param message
* @param <T>
* @return
*/
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
/**
* 判断参数对象是否为null
*
* @param obj
* @return
*/
public static boolean isNull(Object obj) {
return obj == null;
}
/**
* 判断参数对象是否不为null
*
* @param obj
* @return
*/
public static boolean nonNull(Object obj) {
return obj != null;
}
/**
* 检查指定的对象引用是否为空,如果为空则抛出一个自定义的NullPointerException。
*
* 与requireNonNull(Object, String)不同,此方法允许将消息创建延迟到执行空检查之后。
* 虽然在非空情况下这可能会带来性能优势,但在决定调用此方法时,应注意创建消息提供者的成本低于直接创建字符串消息的成本。
* @param obj
* @param messageSupplier
* @param <T>
* @return
*/
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier.get());
return obj;
}