toString、equals和clone

重写toString

  调用对象的toString()方法默认会返回对象在堆内存中的地址值

1
2
3
Object object = new Object();
// 默认输出 类名+@+十六进制哈希值
System.out.println(object.toString());

  重写toString(),即可自定义返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class StringTest {
public static void main(String[] args){
Test test = new Test("测试");
// 将会输出 str: 测试
System.out.println(test);
}
}

class Test{
private String str;

@Override
public String toString() {
return "str:" + this.str;
}

public Test(String str){
this.str = str;
}
}

重写equals

  equals()用于比较两个对象,Object中默认的equal()方法只会比较两个对象的地址值是否相同,所以当我们使用该方法时需要对其进行拓展,比如两个Student对象中如果姓名和学号相同,即认为二者相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Student {
private String name;
private int age;
private String sex;
private int id;

@Override
public boolean equals(Object obj) {
// 如果地址值相同,直接返回true
if (this == obj) return true;

Student stu = (Student)obj;

if (name.equals(stu.name) && (id == stu.id)) {
return true;
}
return false;
}
}

重写clone

浅克隆

  浅克隆只需要实现Cloneable接口,并重写clone方法即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Student implements Cloneable {
private String name;
private int age;
private String sex;
private int id;

public Student(String name, int age, String sex, int id) {
this.name = name;
this.age = age;
this.sex = sex;
this.id = id;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public String getSex() {
return sex;
}

public int getId() {
return id;
}

@Override
protected Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
}

  在其他方法中调用clone()即可实现对象克隆
1
2
3
Student clone = student.clone();
// 注意此时已经重写了toString()
System.out.println(clone);

深克隆

  通过将对象序列化和反序列化实现深克隆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Override
protected Student clone() throws CloneNotSupportedException {
try {
// 序列化
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
// 反序列化
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
return (Student) objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
};