有时需要生成多个相同的对象,最普通的方法就是就是用相同的属性new相同的对象:
public class Main {
public static void main(String[] args) {
Chicken chicken1 = new Chicken(10, 'f', "Tom", 100);
Chicken chicken2 = new Chicken(10, 'f', "Tom", 100);
Chicken chicken3 = new Chicken(10, 'f', "Tom", 100);
}
}
class Chicken {
int age;
char sex;
String name;
double speed;
public Chicken(int age, char sex, String name, double speed) {
this.age = age;
this.sex = sex;
this.name = name;
this.speed = speed;
}
}
这样做的缺点是,如果需要修改一个属性,其他对象的属性就要跟着改一遍,有一个便捷的方法,就是采用 原型模式,从一个对象再创建另外一个可定制的对象,不需要知道任何创建的细节:
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Chicken chicken1 = new Chicken(10, 'f', "Tom", 100);
Chicken chicken2 = (Chicken) chicken1.clone();
System.out.println(chicken1.toString());
System.out.println(chicken2.toString());
}
}
class Chicken implements Cloneable{
int age;
char sex;
String name;
double speed;
public Chicken(int age, char sex, String name, double speed) {
this.age = age;
this.sex = sex;
this.name = name;
this.speed = speed;
}
@Override
public String toString() {
return "Chicken{" +
"age=" + age +
", sex=" + sex +
", name='" + name + '\'' +
", speed=" + speed +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
通过重写Object类的clone方法(必须实现Cloneable接口,不然会抛 CloneNotSupportedException异常),因为clone是native底层的方法,所以会提高性能,并且当要修改其中一属性时,只需对其原型对象(chicken1)修改即可,但上述方法只能对对象里面的值复制,也就是说对于引用类型,上面代码的处理是复制其引用,并不会复制引用的具体对象,所以上述方法被称为 浅克隆(复制),下面来一个 深克隆的例子:
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Chicken chicken1 = new Chicken(10, 'f', "Tom", 100, new Egg("蛋蛋1号", 1));
Chicken chicken2 = (Chicken) chicken1.clone();
System.out.println(chicken1.toString());
System.out.println(chicken2.toString());
chicken1.setEgg(new Egg("蛋蛋2号", 2));
System.out.println(chicken1.toString());
System.out.println(chicken2.toString());
}
}
class Egg implements Cloneable{
private String name;
private int age;
public Egg(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Egg{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
class Chicken implements Cloneable{
private int age;
private char sex;
private String name;
private double speed;
private Egg egg;
public Chicken(int age, char sex, String name, double speed, Egg egg) {
this.age = age;
this.sex = sex;
this.name = name;
this.speed = speed;
this.egg = egg;
}
@Override
public String toString() {
return "Chicken{" +
"age=" + age +
", sex=" + sex +
", name='" + name + '\'' +
", speed=" + speed +
", egg=" + egg +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
Chicken chicken = null;
chicken = (Chicken) super.clone(); //浅复制
chicken.egg = (Egg) egg.clone(); //深复制
return chicken;
}
public void setEgg(Egg egg) {
this.egg = egg;
}
}
这次连鸡里的蛋都是整个对象都给复制了(不是引用复制)