public class Student implements Cloneable{
private String name;
private int age;
private StringBuffer sex;
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 StringBuffer getSex() {
return sex;
}
public void setSex(StringBuffer sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
@Override
protected Student clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return (Student)super.clone();
}
}
public class School implements Cloneable{
private String schoolName; //学校名称
private int stuNums; //学校人数
private Student stu; //一个学生
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public int getStuNums() {
return stuNums;
}
public void setStuNums(int stuNums) {
this.stuNums = stuNums;
}
public Student getStu() {
return stu;
}
public void setStu(Student stu) {
this.stu = stu;
}
@Override
protected School clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
//浅克隆
return (School)super.clone();
}
@Override
protected School clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
School s = null;
s = (School)super.clone();
//手动把字段项克隆,新分配一个对象,让源子对象和克隆对象各自的引用指向不同的对象
s.stu = stu.clone();
return s;
}
@Override
public String toString() {
return "School [schoolName=" + schoolName + ", stuNums=" + stuNums + ", stu=" + stu + "]";
}
}
Cloneable接口的clone方法默认浅拷贝,将浅拷贝变为深拷贝需要我们将大对象中的子对象的类实现Cloneable接口,并在大对象的clone方法中调用子对象clone方法,然后这个子对象便成了深拷贝。String类的唯一性使得克隆的对象在修改String字符串后,源对象和克隆对象的String字符串不一样,产生了深拷贝的幻觉。
int变量是直接在内存中多出一份的stu1和stu2之间的int肯定不同。源stu和克隆stu中String其实也是指向的同一个String对象,由于java的特殊机制,如果修改克隆stu中的String字段会直接产生新的String,所以说不会影响到源stu中的String。
StringBuffer在源对象和克隆对象中是同一个引用,如果想改变StringBuffer对象中的值,需要在克隆对象中手工new StringBuffer()。
Java中的2种数据类型:
基本类型 (primitive types), 四类八种:
整型byte short int long
浮点型float double
逻辑型boolean
字符型char(注意,并没有string的基本类型)
包装类数据
如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部 存在于堆中, Java用new()语句来显示地告诉编译器,在运行时才根据需要动态创建,因此比较灵活,但缺点是要占用更多的时间。