现有一只羊,姓名为tom、年龄为1、颜色为白色;编写程序创建和tom属性完全相同的的10只羊
/***
* @author shaofan
* @Description 传统方式解决克隆羊问题
*/
public class CloneSheep {
public static void main(String[] args) {
Sheep sheep = new Sheep("tom",1,"white");
Sheep sheep1 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep2 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep3 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep4 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep5 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep6 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep7 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep8 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep9 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
Sheep sheep10 = new Sheep(sheep.getName(),sheep.getAge(),sheep.getColor());
}
}
class Sheep{
private String name;
private int age;
private String color;
public Sheep(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
在创建新对象时,总是需要重新获取原始对象的属性如果创建的对象比较复杂,效率较低
总是需要重新初始化对象,而不是动态的获得对象运行的状态,不够灵活

/***
* @author shaofan
* @Description 原型模式解决克隆羊问题
*/
public class CloneSheep {
Sheep sheep = new Sheep("tom",1,"white");
Sheep sheep1 = sheep.clone();
}
class Sheep implements Cloneable{
private String name;
private int age;
private String color;
public Sheep(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
protected Sheep clone(){
Sheep sheep = null;
try{
sheep = (Sheep) super.clone();
}catch (CloneNotSupportedException e){
System.out.println(e.getMessage());
}
return sheep;
}
}

Spring在配置bean时可以指定Singleton或Prototype,在调用getBean方法时会走到AbstractBeanFactory的doGetBean中,这里判断配置时单例还是原型然后返回对应的实例
/***
* @author shaofan
* @Description 克隆羊深拷贝
*/
public class CloneSheep {
public static void main(String[] args) throws CloneNotSupportedException, IOException {
// 重写克隆方法
Sheep sheep = new Sheep("tom",1,"white",new Sheep("jack",2,"black",null));
Sheep sheep1 = sheep.clone();
System.out.println(sheep.getFriend()==sheep1.getFriend());
// 序列化方式
Sheep sheep2 = sheep.deepClone();
System.out.println(sheep2);
System.out.println(sheep2.getFriend()==sheep.getFriend());
}
}
class Sheep implements Cloneable,Serializable{
private String name;
private int age;
private String color;
private Sheep friend;
public Sheep(String name, int age, String color, Sheep friend) {
this.name = name;
this.age = age;
this.color = color;
this.friend = friend;
}
public Sheep getFriend() {
return friend;
}
public void setFriend(Sheep friend) {
this.friend = friend;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
", friend=" + friend +
'}';
}
@Override
protected Sheep clone() throws CloneNotSupportedException {
Sheep sheep = (Sheep) super.clone();
if(sheep.friend!=null){
sheep.setFriend(sheep.friend.clone());
}
return sheep;
}
public Sheep deepClone() throws IOException {
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try{
// 序列化为字节流
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
return (Sheep) ois.readObject();
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
if(bos!=null){
bos.close();
}
if(bis!=null){
bis.close();
}
if(oos!=null){
oos.close();
}
if(ois!=null){
ois.close();
}
}
}
}