Java之Objects工具类
JDK 8
---
看到一些方法使用了 Objects.requireNonNull 这个函数,用来判断参数是否为null,为null时就抛出 NullPointerException。
于是便来看看 Objects 这个工具类 提供了哪些公共的方法可用,并做了简单的测试。
其中,deepEquals、hash 底层 用了 另一个工具类 Arrays 提供的方法来实现。
测试代码:
package aug;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.Consumer;
/**
* 测试Objects工具类
* @author ben
* @date 2021-08-11 09:41:27 CST
*/
public class Test081101 {
private static Consumer<Object> cs = System.out::println;
public static void main(String[] args) {
// compare(T, T, Comparator<? super T>)
cs.accept("测试compare:");
int ret = Objects.compare(null, null, null);
cs.accept("ret=" + ret); // 0
Person p1 = new Person("p1", 6);
Person p2 = new Person("p2", 66);
Comparator<Person> cpt = (o1, o2)->{
// 根据年龄age
return o1.getAge() - o2.getAge();
};
ret = Objects.compare(p1, p2, cpt);
cs.accept("ret=" + ret);
// equals(Object, Object)
cs.accept("\n测试equals:");
cs.accept(Objects.equals(null, null));
cs.accept(Objects.equals(p1, null));
cs.accept(Objects.equals(p1, p2));
Person p3 = p1;
cs.accept(Objects.equals(p1, p3));
// deepEquals(Object, Object)
// 基于值相等,重点拥有数组判断
cs.accept("\n测试deepEquals:");
Org org1 = new Org("org");
Org org2 = new Org("org");
cs.accept("== = " + (org1 == org2));
cs.accept("equals = " + Objects.equals(org1, org2));
cs.accept("deepEquals = " + Objects.deepEquals(org1, org2));
org1.getPlist().add(p1);
org2.getPlist().add(p2);
cs.accept("\n== = " + (org1 == org2));
cs.accept("equals = " + Objects.equals(org1, org2));
cs.accept("deepEquals = " + Objects.deepEquals(org1, org2));
Person p4 = new Person("p1", 6);
org2.getPlist().clear();
org2.getPlist().add(p4);
cs.accept("\n== = " + (org1 == org2));
cs.accept("equals = " + Objects.equals(org1, org2));
cs.accept("deepEquals = " + Objects.deepEquals(org1, org2));
// 数组deepEquals
// size、顺序、值相等才是true
cs.accept("\n测试数组deepEquals:");
int[] iarr1 = {1,2,3,4,5};
int[] iarr2 = {1,2,3,4,5};
int[] iarr3 = {0,0,3,4,5};
cs.accept(Objects.equals(iarr1, iarr2));
cs.accept(Objects.deepEquals(iarr1, iarr2));
cs.accept(Objects.deepEquals(iarr1, iarr3));
cs.accept(Objects.deepEquals(null, null));
// hash(Object...)
// 底层调用 Arrays.hashCode
cs.accept("\n测试hash:");
cs.accept("null=\n" + Objects.hash(null)); // 0
cs.accept(Objects.hash(new Object[] {})); // 1
cs.accept(Objects.hash(new Object[] {null})); // 31
cs.accept("p1=\n" + p1.hashCode()); // 不等
cs.accept(Objects.hash(p1));
cs.accept("org1=\n" + org1.hashCode()); // 不等
cs.accept(Objects.hash(org1));
cs.accept("iarr1=\n" + iarr1.hashCode()); // 不等
cs.accept(Objects.hash(iarr1));
// hashCode(Object)
// 底层调用对象的 o.hashCode()
cs.accept("\n测试hashCode:");
cs.accept(Objects.hashCode(null)); // 0
cs.accept("p1=\n" + p1.hashCode()); // 相同
cs.accept(Objects.hashCode(p1));
cs.accept("org1=\n" + org1.hashCode()); // 相同
cs.accept(Objects.hashCode(org1));
cs.accept("iarr1=\n" + iarr1.hashCode()); // 相同
cs.accept(Objects.hashCode(iarr1));
// isNull(Object)
cs.accept("\n测试isNull:");
cs.accept(Objects.isNull(null));
cs.accept(Objects.isNull(p1));
cs.accept(Objects.isNull(iarr1));
cs.accept(Objects.isNull(123));
// nonNull(Object)
// 和 isNull 相反
cs.accept("\n测试nonNull:");
cs.accept(Objects.nonNull(null));
cs.accept(Objects.nonNull(p1));
cs.accept(Objects.nonNull(iarr1));
cs.accept(Objects.nonNull(123));
// requireNonNull
cs.accept("\n测试requireNonNull:");
// func1(null); // java.lang.NullPointerException
func1(123);
// func2(null); // java.lang.NullPointerException
func2(p1);
// toString
// 底层调用 String.valueOf
cs.accept("\n测试toString(Object):");
cs.accept(Objects.toString(null));
cs.accept(Objects.toString(p1));
cs.accept(Objects.toString(123));
cs.accept("\n测试toString(Object, String):");
// 第一个参数为 null,则,返回第二个参数(默认值)
cs.accept(Objects.toString(null, "param2"));
cs.accept(Objects.toString(p1, "param2"));
cs.accept(Objects.toString(123, "param2"));
}
public static void func1(Integer param) {
// null 时 抛出异常
Objects.requireNonNull(param);
// 测试和断言的区别
// 增加参数-enableassertions或者-ea打开断言
// assert param != null; // java.lang.AssertionError
cs.accept("func1=" + param);
}
public static void func2(Person param) {
// null 时 抛出异常,异常信息 为 第二个参数
Objects.requireNonNull(param, "func2-param can't be null");
cs.accept("func2=" + param);
}
}
两个POJO
@Data
public class Org {
private String name;
private List<Person> plist;
public Org(String name) {
this.name = name;
this.plist = new ArrayList<Person>(4);
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
private String name;
private Integer age;
}
// 注:@Data等注解来自 lombok,用来自动产生 getter、setter、构造函数等,,其还有更丰富的功能
/*
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
*/
执行结果:
测试compare:
ret=0
ret=-60
测试equals:
true
false
false
true
测试deepEquals:
== = false
equals = true
deepEquals = true
== = false
equals = false
deepEquals = false
== = false
equals = true
deepEquals = true
测试数组deepEquals:
false
true
false
true
测试hash:
null=
0
1
31
p1=
211226
211257
org1=
6722910
6722941
iarr1=
1705736037
1705736068
测试hashCode:
0
p1=
211226
211226
org1=
6722910
6722910
iarr1=
1705736037
1705736037
测试isNull:
true
false
false
false
测试nonNull:
false
true
true
true
测试requireNonNull:
func1=123
func2=Person(name=p1, age=6)
测试toString(Object):
null
Person(name=p1, age=6)
123
测试toString(Object, String):
param2
Person(name=p1, age=6)
123
补:
有一个 Google的Guava包,里面也提供了一个 Objects工具类,提供了以下公开方法(guava-19.0.jar),可以进一步探究。
equal(Object, Object)
firstNonNull(T, T)
hashCode(Object...)
toStringHelper(Class<?>)
toStringHelper(Object)
toStringHelper(String)