1.clone(),克隆方法(深度克隆)
使用克隆方法改变克隆对象的某个属性,而原对象属性不改变。以一个用户拥有一本书为例:
在User类中接入接口Cloneable并重写clone()方法。
//重写clone方法
@Override
protected User clone() {
//初始化user
User user = null;
try {
//调用克隆方法
user = (User) super.clone();
//判断非空,调用克隆方法,对book的克隆
if (user.book != null) {
user.book = book.clone();
}
return user;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
在Book类接入接口Cloneable,重写clone()方法。
//重写clone方法
@Override
protected Book clone() {
try {
return (Book) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
在测试类中进行测试:
public static void main(String[] args) {
User user=new User("晓晓",18);
Book book=new Book(1,"《笑傲江湖》");
user.setBook(book);
test1(user);
System.out.println(user);
}
private static void test1(User user) {
//user2为user的克隆
User user2=user.clone();
user2.setName("泉泉");
user2.getBook().setBookName("《百年好合》");
System.out.println(user2);
}
测试结果比对:
未克隆结果:改变user2的name,user也发生改变
User{name='晓晓', age=18, book=Book{id=1, bookName='《百年好合》'}}
User{name='晓晓', age=18, book=Book{id=1, bookName='《百年好合》'}}
User{name='泉泉', age=18, book=Book{id=1, bookName='《百年好合》'}}
User{name='泉泉', age=18, book=Book{id=1, bookName='《百年好合》'}}
克隆后:改变user2的name和bookName属性,user不改变。
User{name='泉泉', age=18, book=Book{id=1, bookName='《百年好合》'}}
User{name='晓晓', age=18, book=Book{id=1, bookName='《笑傲江湖》'}}
2.equals()、hashCode()重写
equals()方法比较对象时比较的是值,但是在比较两个对象内容时就会出现失真的情况,这时就需要重写equals()方法;
//重写hashCode()方法
@Override
public int hashCode() {
return Objects.hash(id, name, age);
}
//重写equals()方法
@Override
public boolean equals(Object obj) {
//判断两对象的值是否相等
if(this==obj)return true;
//判断传入的对象是否为空
if (obj == null) return false;
//getClass() != o.getClass() 当前的类 和传入 对象的类 不是同一个类
if (obj.getClass() != this.getClass()) return false;
//强制转换 传入的object 为 Student类型
Student student = (Student) obj;
//判断传入对象的某个属性是否为空、是否与比较对象的属性内容相等,值是否相等
boolean a=(student.id!=null&&this.id.equals(student.id))||this.id==student.id;
boolean b=(student.age!=null&&this.age.equals(student.age))||this.age==student.age;
boolean c=(student.name!=null&&this.name.equals(student.name))||this.name==student.name;
return a&&b&&c;
}