创建型 - 原型模式
程序员文章站
2022-06-13 15:25:12
...
前言
1.原型模式是使用克隆方式来生成对象
2.测试类代码偏多,是为了探索基本类型、引用类型(String),自定义引用类型(年级Grade)与克隆方法之间的联系
3.知识点一:Java克隆类必须实现Cloneable接口,并重写clone()方法
4.知识点二:调用clone()方法所得到的对象,是一个全新的对象,不是对原对象的引用
5.知识点三:基本类型的成员变量(年龄age)不会因为原对象的值改变而发生变化
6.知识点四:String类型的成员变量(姓名name)只有当成员变量的值完全一致的时候,才会引用同一个String对象
7.知识点五:自定义引用类型的成员变量(年级Grade) 在调用Student对象clone()方法,只复制引用(浅克隆)
8.知识点六:自定义引用类型的成员变量(年级Grade)如果不想复制引用,可以调用原对象成员变量Grade对象 的clone()方 法,来生成一个全新的Grade对象(深克隆)
9.源码下载:百度网盘 提取码:9j11
一、学生类
/**
* 学生类
* @author ywl
*/
public class Student implements Cloneable{
/**
* 引用类型(String) 学生姓名
* String类型在java属于不可变对象,一旦name值改变,意味着原来的值被抛弃
* clone()之后,若原name值改变,新对象的name值仍然指向原来字符串内存地址
*/
private String name;
/**
* 基本类型 学生年龄
* clone()之后,会将原值一并复制
*/
private Integer age;
//private int age;
/**
* 引用类型
* 若Grade未赋值,则值为null,clone()之后,新对象也为null
*/
private Grade grade;
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 Grade getGrade() {
return grade;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public Student clone() throws CloneNotSupportedException {
return (Student)super.clone();
}
}
二、学生年级类
/**
* 学生年级类
* @author ywl
*/
public class Grade implements Cloneable{
public Grade clone() throws CloneNotSupportedException {
return (Grade)super.clone();
}
}
三、测试类
/**
* 测试类
* @author ywl
*/
public class TestMain {
public static final int TYPE_ONE = 1;
public static final int TYPE_TWO = 2;
public static final int TYPE_THREE = 3;
public static void main(String[] args) throws CloneNotSupportedException {
//判断克隆对象与原对象是否同一个?(内存地址是否相同)
//testObject();
//判断基本类型属性(年龄age,int类型)
//testInt(TYPE_TWO);
//判断String类型
//testString(TYPE_THREE);
//判断Grade类型
testGrade(TYPE_THREE);
}
/**
* 检验克隆对象与原对象是否同一个?(内存地址是否相同)
* @throws CloneNotSupportedException
*/
private static void testObject() throws CloneNotSupportedException{
Student zhangsan = new Student();
Student lisi = zhangsan.clone();
System.out.println(String.format("原对象内存地址:[%s]",zhangsan));
System.out.println(String.format("克隆对象内存地址:[%s]",lisi));
System.out.println(zhangsan == lisi
? "原对象与克隆对象是同一个对象"
: "原对象与克隆对象不是同一个对象");
/** 以上测试结果
* 原对象内存地址:[[email protected]]
* 克隆对象内存地址:[[email protected]]
* 原对象与克隆对象不是同一个对象
*/
}
/**
* 检验基本类型int的复制情况
* @param type 测试类型
* @throws CloneNotSupportedException
*/
private static void testInt(int type) throws CloneNotSupportedException{
Student zhangsan = null;
Student lisi = null;
//原对象
if(TYPE_ONE == type) {
zhangsan = new Student();
zhangsan.setAge(12);
lisi = zhangsan.clone();
/**
* 以上测试结果:
* 原对象年龄:[12]
* 克隆对象年龄:[12]
* 原对象与克隆对象年龄一致
*/
} else if(TYPE_TWO == type) {
//原对象修改年龄后 (包装类型与基本类型以上测试结果一致)
zhangsan = new Student();
zhangsan.setAge(12);
lisi = zhangsan.clone();
zhangsan.setAge(13);
/**
* 以上测试结果:
* 原对象年龄:[13]
* 克隆对象年龄:[12]
* 原对象修改年龄后与克隆对象年龄不一致
*/
} else {
throw new RuntimeException("未定义的类型");
}
System.out.println(String.format("原对象年龄:[%s]", zhangsan.getAge()));
System.out.println(String.format("克隆对象年龄:[%s]", lisi.getAge()));
System.out.println(zhangsan.getAge() == lisi.getAge()
? "原对象与克隆对象年龄一致"
: "原对象与克隆对象年龄不一致");
}
/**
* 检验String类型
* @param type 测试类型
* @throws CloneNotSupportedException
*/
private static void testString(int type) throws CloneNotSupportedException{
Student zhangsan = null;
Student lisi = null;
if(TYPE_ONE == type) {
zhangsan = new Student();
lisi = zhangsan.clone();
zhangsan.setName("张三");
/**
* 以上测试结果
* 原对象姓名:[张三]
* 克隆对象姓名:[null]
* 原对象与克隆对象姓名不是同一个引用
*/
} else if(TYPE_TWO == type){
zhangsan = new Student();
zhangsan.setName("张三");
lisi = zhangsan.clone();
zhangsan.setName("李四");
/**
* 以上测试结果:
* 原对象姓名:[李四]
* 克隆对象姓名:[张三]
* 原对象与克隆对象姓名不是同一个引用
*/
} else if (TYPE_THREE == type){
zhangsan = new Student();
zhangsan.setName("张三");
lisi = zhangsan.clone();
zhangsan.setName("张三");
/**
* 以上测试结果:
* 原对象姓名:[张三]
* 克隆对象姓名:[张三]
* 原对象与克隆对象姓名是同一个引用
*/
} else {
throw new RuntimeException("未定义的类型");
}
System.out.println(String.format("原对象姓名:[%s]",zhangsan.getName()));
System.out.println(String.format("克隆对象姓名:[%s]",lisi.getName()));
System.out.println(zhangsan.getName() == lisi.getName()
? "原对象与克隆对象姓名是同一个引用"
:"原对象与克隆对象姓名不是同一个引用");
}
/**
* 校验Grade(引用类型)
* @param type 测试类型
* @throws CloneNotSupportedException
*/
private static void testGrade(int type) throws CloneNotSupportedException{
Student zhangsan = null;
Student lisi = null;
if(TYPE_ONE == type){
zhangsan = new Student();
lisi = zhangsan.clone();
zhangsan.setGrade(new Grade());
/**
* 以上测试结果
* 原对象班级:[[email protected]]
* 克隆对象班级:[null]
* 原对象与克隆对象班级不是同一个引用
*/
} else if(TYPE_TWO == type) {
zhangsan = new Student();
zhangsan.setGrade(new Grade());
lisi = zhangsan.clone();
/**
* 以上测试结果
* 原对象班级:[[email protected]]
* 克隆对象班级:[[email protected]]
* 原对象与克隆对象班级是同一个引用
*/
} else if(TYPE_THREE == type){
zhangsan = new Student();
zhangsan.setGrade(new Grade());
lisi = zhangsan.clone();
lisi.setGrade(zhangsan.getGrade().clone());
/**
* 以上测试结果:
* 原对象班级:[[email protected]]
* 克隆对象班级:[[email protected]]
* 原对象与克隆对象班级不是同一个引用
*/
} else {
throw new RuntimeException("未定义的类型");
}
System.out.println(String.format("原对象班级:[%s]",zhangsan.getGrade()));
System.out.println(String.format("克隆对象班级:[%s]",lisi.getGrade()));
System.out.println(zhangsan.getGrade() == lisi.getGrade()
? "原对象与克隆对象班级是同一个引用"
:"原对象与克隆对象班级不是同一个引用");
}
}
上一篇: Es6 有关 let const 字符串 数组 等的小结
下一篇: springboot_工程部署