Objects:专为操作Java对象而生的工具类
9.4 Objects工具类
Java 的 Objects 类是一个实用工具类,包含了一系列静态方法,用于处理对象。它位于 java.util 包中,自 Java 7 引入。Objects 类的主要目的是降低代码中的空指针异常 (NullPointerException) 风险,同时提供一些非常实用的方法供我们使用。
对象判空
在 Java 中,万物皆对象,对象的判空可以说无处不在。Objects 的 isNull
方法用于判断对象是否为空,而 nonNull
方法判断对象是否不为空。例如:
Integer integer = new Integer(1);
if (Objects.isNull(integer)) {
System.out.println("对象为空");
}
if (Objects.nonNull(integer)) {
System.out.println("对象不为空");
}
对象为空时抛异常
如果我们想在对象为空时,抛出空指针异常,可以使用 Objects 的 requireNonNull
方法。例如:
Integer integer1 = new Integer(128);
Objects.requireNonNull(integer1);
Objects.requireNonNull(integer1, "参数不能为空");
Objects.requireNonNull(integer1, () -> "参数不能为空");
判断两个对象是否相等
我们经常需要判断两个对象是否相等,Objects 给我们提供了 equals
方法,能非常方便的实现:
Integer integer1 = new Integer(1);
Integer integer2 = new Integer(1);
System.out.println(Objects.equals(integer1, integer2));
执行结果:
true
但使用这个方法有坑,比如例子改成:
Integer integer1 = new Integer(1);
Long integer2 = new Long(1);
System.out.println(Objects.equals(integer1, integer2));
执行结果:
false
不过,需要注意的是,虽然 Objects.equals()
方法本身是用来避免坑的,因为它可以处理 null 值的比较,而不会抛出空指针异常。然而,这并不意味着它没有任何潜在问题。实际上,Objects.equals()
方法的一个潜在问题是依赖于被比较对象的 equals()
方法实现。
当两个对象的类没有正确实现 equals()
方法时,Objects.equals()
方法可能会产生不符合预期的结果。举个例子:
public class ObjectsDemo1 {
public static void main(String[] args) {
Person person1 = new Person("沉默王二", 18);
Person person2 = new Person("沉默王二", 18);
System.out.println(Objects.equals(person1, person2)); // 输出:false
}
}
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
在上面的例子中,我们创建了一个名为 Person 的类,但是没有重写 equals()
方法。然后我们创建了两个具有相同属性的 Person 对象,并使用 Objects.equals()
方法比较它们。尽管这两个对象的属性是相同的,但输出结果却是 false。这是因为 Objects.equals()
方法依赖于对象的 equals()
方法,而在这个例子中,Person 类没有正确地实现 equals()
方法,所以默认情况下会使用 Object 类的 equals()
方法,它只比较对象引用是否相同。
为了解决这个问题,我们需要在 Person 类中重写 equals()
方法:
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
现在,当我们使用 Objects.equals()
方法比较两个具有相同属性的 Person 对象时,输出将是 true,符合我们的预期。
获取对象的hashCode
如果你想获取某个对象的 hashCode,可以使用 Objects 的 hashCode
方法。例如:
String str = new String("沉默王二");
System.out.println(Objects.hashCode(str));
执行结果:
867758096
比较两个对象
compare()
方法用于比较两个对象,通常用于自定义排序。它需要一个比较器 (Comparator) 作为参数。如果比较器为 null,则使用自然顺序。以下是一个 compare()
方法的示例:
class ObjectsCompareDemo {
public static void main(String[] args) {
PersonCompare person1 = new PersonCompare("itwanger", 30);
PersonCompare person2 = new PersonCompare("chenqingyang", 25);
Comparator<PersonCompare> ageComparator = Comparator.comparingInt(p -> p.age);
int ageComparisonResult = Objects.compare(person1, person2, ageComparator);
System.out.println("年龄排序: " + ageComparisonResult); // 输出:1(表示 person1 的 age 在 person2 之后)
}
}
class PersonCompare {
String name;
int age;
PersonCompare(String name, int age) {
this.name = name;
this.age = age;
}
}
比较两个数组
deepEquals()
用于比较两个数组类型的对象,当对象是非数组的话,行为和 equals()
一致。
int[] array1 = {1, 2, 3};
int[] array2 = {1, 2, 3};
int[] array3 = {1, 2, 4};
System.out.println(Objects.deepEquals(array1, array2)); // 输出:true(因为 array1 和 array2 的内容相同)
System.out.println(Objects.deepEquals(array1, array3)); // 输出:false(因为 array1 和 array3 的内容不同)
// 对于非数组对象,deepEquals() 的行为与 equals() 相同
String string1 = "hello";
String string2 = "hello";
String string3 = "world";
System.out.println(Objects.deepEquals(string1, string2)); // 输出:true(因为 string1 和 string2 相同)
System.out.println(Objects.deepEquals(string1, string3)); // 输出:false(因为 string1 和 string3 不同)
再来个二维数组的:
String[][] nestedArray1 = {{"A", "B"}, {"C", "D"}};
String[][] nestedArray2 = {{"A", "B"}, {"C", "D"}};
String[][] nestedArray3 = {{"A", "B"}, {"C", "E"}};
System.out.println(Objects.deepEquals(nestedArray1, nestedArray2)); // 输出:true (因为嵌套数组元素相同)
System.out.println(Objects.deepEquals(nestedArray1, nestedArray3)); // 输出:false (因为嵌套数组元素不同)
小结
除了上面提到的这些方法,Objects 还提供了一些其他的方法,比如说 toString,感兴趣的话可以试一下。
总之,Objects 类提供的这些方法在许多情况下还是非常有用得,可以简化代码并减少出错的可能性。
GitHub 上标星 10000+ 的开源知识库《二哥的 Java 进阶之路》第一版 PDF 终于来了!包括Java基础语法、数组&字符串、OOP、集合框架、Java IO、异常处理、Java 新特性、网络编程、NIO、并发编程、JVM等等,共计 32 万余字,500+张手绘图,可以说是通俗易懂、风趣幽默……详情戳:太赞了,GitHub 上标星 10000+ 的 Java 教程
微信搜 沉默王二 或扫描下方二维码关注二哥的原创公众号沉默王二,回复 222 即可免费领取。