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)

 

posted @ 2021-08-11 11:05  快乐的欧阳天美1114  阅读(224)  评论(0编辑  收藏  举报