常用API
Object
Object类的作用
- 一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类
- Object类的方法是一切子类都可以直接使用的
Object类的常用方法
方法名 | 说明 |
---|---|
public String toString() | 默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址 |
public Boolean equals(Object o) | 默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false |
toString()方法
-
测试代码:
package com.java.apitest; public class Test { public static void main(String[] args) { Student s = new Student("张三", '男', 20); String rs = s.toString(); // 以下语句均返回对象地址值com.java.apitest.Student@3b07d329 // 以下语句默认调用Student类重写后的toString()方法,此时以下语句将打印对象的内容数据 System.out.println(rs); System.out.println(s.toString()); System.out.println(s); } }
-
问题引出:
- 开发中直接输出对象,默认输出对象的地址其实是毫无意义的
- 开发中输出对象变量,更多的时候是希望看到对象的内容数据而不是对象的地址信息
-
toString()的存在意义:
- 父类toString()方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址信息
因此上述测试代码的中涉及的Student类代码:
package com.java.apitest; public class Student { private String name; private char sex; private int age; public Student() { } public Student(String name, char sex, int age) { this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", sex=" + sex + ", age=" + age + '}'; } }
使用Alt + Inster实现快速生成本类的toString()方法
或者编辑toS,两次回车自动生成当前类的toString()方法
equals()方法
-
测试代码:
package com.java.apitest; /** * Object类中equals()方法的使用 */ public class Test2 { public static void main(String[] args) { Student s1 = new Student("张三", '男', 20); Student s2 = new Student("李四", '女', 20); System.out.println(s1.equals(s2)); // false,比较地址值 } }
-
问题引出:
- 直接比较两个对象的地址是否相同完全可以使用“==”代替equals
-
equals存在的意义
- 父类equals方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则
在之前的Student类中重写equals
@Override public boolean equals(Object o) { // 判断o是不是学生类型 if (o instanceof Student) { // 判断两个对象的内容是否一样 Student s2 = (Student) o; //o是Object类型,必须发生强转,因为Object里面是没有name的 //注意在进行字符串内容的比较时,一定使用equals而不是== //在进行基本数据类型的比较时,应该使用== if (this.name.equals(s2.name) && this.age == (s2.age) && this.sex == (s2.sex)) { return true; /*简化写法 return this.name.equals(s2.name) && this.age == (s2.age) && this.sex == (s2.sex); */ } } else { return false; } return false; }
当我们需要比较基本数据类型内容,使用== ,当我们需要比较对象内容,重写equals
-
使用快捷键Alt + Inster快速生成equals
连续点击三次下一步,并将生成的hashCode()重写方法删除
@Override public boolean equals(Object o) { // 判断是否是同一个对象比较,如果是返回true if (this == o) return true; // 如果为空返回false // 如果比较类型和传进来的类型(被比较类型)不同返回false if (o == null || getClass() != o.getClass()) return false; // 此时说明o一定是学生类型且不为null Student student = (Student) o; return sex == student.sex && age == student.age && Objects.equals(name, student.name); }
Object的equals更安全
Objects
Objects常见方法
方法名 | 说明 |
---|---|
public static boolean equals(Object a, Object b) | 比较两个对象的,底层会先进行非空判断,从而 可以避免空指针异常,再进行equals比较 |
public static boolean isNull(Object obj) | 判断变量是否为null,为null返回true,反之,返回false |
Objects概述及equals方法
Object类与Object还是继承关系,Objects类是从JDK1.7开始之后才有
-
回顾之前的自动生成的equals和自己写的equals,发现官方使用的是Objects的
即官方在进行字符串比较时,没有对象自己的equals方法,而是选择了Objects的equals方法来比较两个对象
Objects的equals方法比较的结果是一样的,但是更安全(做了非空校验)
-
测试代码
package com.java.apitest; import java.util.Objects; public class Test3 { public static void main(String[] args) { /* String s1 = "张三"; String s2 = new String("张三"); System.out.println(s1.equals(s2)); // true */ String s1 = null; String s2 = new String("张三"); //System.out.println(s1.equals(s2)); // 空指针异常, Cannot invoke "String.equals(Object)" because "s1" is null System.out.println(Objects.equals(s1, s2)); // false /*Objects中equals的源码: public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); } */ } }
用法:sout(Objects.equals(A,B))
Objects的isNull方法
System.out.println(Objects.isNull(s1));
System.out.println(Objects.isNull(s2));
//等价于
//sout(s1 == null);
//sout(s2 == null);
小结:当我们进行对象信息内容的比较时,建议使用objects的equals方法,它更加安全