回顾一下API的概念
什么是API?
- API(Application Programming interface):应用程序编程接口
- 就是Java帮我们已经写好一些程序,如:类、方法等,我们直接拿过来用就可以解决一些问题。
学习使用一些别人写好的程序,可以帮助我们提高开发效率;而API的学习可以到API文档汇中进行查询。(最常用的只有java.base这个模块下的一些API)
接下来我们学习第一个常用的API——Object
Object类的作用
- Object类是Java中所有类的祖宗类,因此,Java中所有类的对象都可以直接使用object类中提供的一些方法。
Object类的常见方法
方法名 | 说明 |
public String toString() | 返回对象的字符串表示形式 |
public boolean equals(Object o) | 判断两个对象是否相等。 |
protected Object clone() | 对象克隆 |
toString方法
前面我们讲过,直接使用toString方法,通常只会输出对象的地址;toString出现的意义也是为了让我们自己重写它并让它输出对象的各种数据。
以学生类为例(
变量:
private String name;
private char sex;
private double score;
)
@Override public String toString() { return "Student{" + "name='" + name + '\'' + ", sex=" + sex + ", score=" + score + '}'; }
equals方法
正常调用equals方法,比较的是两个目标对象的地址是否一样;同样也需要根据需求重写equals方法来实现比较两个对象内部的内容是否一致的功能。
public class Test { public static void main(String[] args) { Student s1 = new Student("元仲辛",'男',100); Student s2 = new Student("元仲辛",'男',100); System.out.println(s2.equals(s1)); //没重写方法,比较的是地址 System.out.println(s1 == s2); //与该写法是一样的效果,并不会去比较对象内部的内容 //输出结果都为false } }
运行结果:
现在在IDEA中对equals也进行重写:
傻瓜式点击下一步即可。
@Override public boolean equals(Object o) { //1.判断两个对象是否地址一样,一样则直接返回true if (this == o) return true; //2.判断o是null直接返回false,或者比较者的类型与被比较者的类型不一样,返回false if (o == null || getClass() != o.getClass()) return false; //3. 满足o不是null,且o一定是学生类型的对象,就可以开始比较内容了 Student student = (Student) o; return sex == student.sex && Double.compare(student.score, score) == 0 && Objects.equals(name, student.name); //这里比较的一些方法在后面的API会学习到 }
clone方法
这个方法并不是开发中的重点,只是在阅读一些源码的时候,偶尔会遇到的,我们简单地了解一下就可以了。
对象克隆,也就是:
- 当某个对象调用这个方法时,这个方法会复制一个一模一样的新对象返回。
要注意的是,clone方法是用protected修饰的,说明它是一个受保护的方法,protected修饰的方法,它只能在Object类所在的包下或者Object类的子类中才能去访问它,而即使是子类对象也不能直接访问。
作为Object类的子类,其子类对象需要重写clone方法,该子类对象才可以使用clone方法
@Override protected Object clone() throws CloneNotSupportedException { //super去调用分类Object中的clone方法。 return super.clone(); }
在Java中,不是所有类都可以克隆的,需要实现一个接口:
该接口中什么都没有,在开发中,如果一个接口什么都没有,我们就把它称之为标记接口。
可以把它理解成一种规则,必须要实现这个接口,满足了这个规则了,这个类的对象才拥有了克隆的能力。
做好了一切准备之后,我们第一次调用这个clone方法时,它一般会报错;会提醒你这个克隆方法可能还有一些其他代码写得有问题,很容易出错,它会通过报错的方式提醒我们(异常)。我们暂时可以使用“ Alt + Enter” 将提醒抛出去,代码就不会报错了。(关于这个细节,是我们后面才会将的技术)
public class Test { public static void main(String[] args) throws CloneNotSupportedException { Student s1 = new Student("元仲辛",'男',100); System.out.println(s1); System.out.println(s1.getName()); System.out.println(s1.getSex()); System.out.println(s1.getScore()); System.out.println("--------------------"); Student s2 = (Student) s1.clone(); System.out.println(s2); System.out.println(s2.getName()); System.out.println(s2.getSex()); System.out.println(s2.getScore()); } }
运行结果:
以上所讲的克隆,实际上属于浅克隆,也就是说,克隆分为两种:浅克隆和深克隆。
浅克隆
- 拷贝出的新对象,与原对象中的数据一模一样(引用类型拷贝的只是地址)
深克隆
- 象中基本类型的数据直接拷贝。
- 对象中的字符串数据拷贝的还是地址。
- 对象中还包含的其他对象,不会拷贝地址,会创建新对象。
深克隆实现:(对于包含数组或者其他对象的)
1. pacpackage user.APITest; import java.util.Arrays; public class User implements Cloneable{ private String name; private char gender; private String[] subjects = new String[3]; //深克隆 @Override protected Object clone() throws CloneNotSupportedException { User u2 = (User) super.clone(); u2.subjects = u2.subjects.clone(); //单独对引用类型进行克隆 return u2; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", gender=" + gender + ", subjects=" + Arrays.toString(subjects) + '}'; } public User(String name, char gender, String[] subjects) { this.name = name; this.gender = gender; this.subjects = subjects; } public User() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public String[] getSubjects() { return subjects; } public void setSubjects(String[] subjects) { this.subjects = subjects; } }
public class Test { public static void main(String[] args) throws CloneNotSupportedException { String[] s = new String[]{"物理","生物","地理"}; User u1 = new User("张三",'男',s); System.out.println(u1.toString()); System.out.println(u1.getSubjects()); System.out.println("--------------"); User u2 = (User) u1.clone(); System.out.println(u2.toString()); System.out.println(u2.getSubjects()); } }
这样深克隆出来的数组就不只是复制地址了:
总结
1、Object中toString方法的作用是什么?存在的意义是什么?
- 基本作用:返回对象的字符串形式。
- 存在的意义:让子类重写,以便返回子类对象的内容。
2、Object中equals方法的作用是什么?存在的意义是什么?
- 基本作用:默认是比较两个对象的地址是否相等。
- 存在的意义:让子类重写,以便用于比较对象的内容是否相同。
3、什么是对象克隆?
- 当某个对象调用这个方法时,这个方法会复制一个一模一样的新对象返回。
4、什么是浅克隆?
- 拷贝出的新对象,与原对象中的数据一模一样(引用类型拷贝的只是地址)
5、什么是深克隆?
- 对象中基本类型的数据直接拷贝。
- 对象中的字符串数据拷贝的还是地址。
- 对象中还包含的其他对象,不会拷贝地址,会创建新对象。
END