一个自定义Object,它里面的属性如果是Wrapper Class对象类型
二:Wrapper Class(基本数据类型的包装类型):是对象的类型
Wrapper Class都有哪些:
基本数据类型
占用内存大小
包装类(Wrapper Class)
byte
1byte
Byte
short
2bytes
Short
int
4bytes
Integer
long
8bytes
Long
float
4bytes
Float
double
8bytes
Double
boolean
1bit
Boolean
char
2bytes
Character
在自定义类Person中添加一个新的Integer属性
package tt.vo;
public class Person implements Cloneable {
// 基本数据类型
private int age;
// Wrapper Class类型
private Integer height;
@Override
public Person clone() throws CloneNotSupportedException {
Person p = (Person) super.clone();
return p;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [age=" + age + ", height=" + height + "]";
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
---------------------------------------------------------------下面开始测试了------------------------------------------------------------------
测试类TestMain:
package tt;
import tt.vo.Person;
public class TestMain {
public static void main(String[] args) throws CloneNotSupportedException {
// initialize Person p
Person p = new Person();
p.setAge(18);
p.setHeight(162);
System.out.println("p:" + p);
Person pclone = p.clone();
System.out.println("pclone:" + pclone);
System.out.println("p.getHeight()==pclone.getHeight(): "+(p.getHeight()==pclone.getHeight()?"true":"false"));
}
}
debug截图:
(ps: 每次debug时候,id所分配的号码会不一样)
通过debug可以发现:
- p和pclone的id不一样,说明p和pclone分别指向了两个不同的Person对象
- Person对象新增的Integer属性(height)是对象的类型,所以有id
- p.height和pclone.height的id(24)是相同的!
- 说明,默认的clone()方法,对于对象的类型来说,都是浅克隆。
- debug展开height内部看来:其Integer内部是维护了一个int基本类型的value
我们来看看Integer类的源代码,进一步证实一下,
private final int value;
我们来看看,这些Wrapper Class其内部对应维护的,基本的数据类型吧
包装类(Wrapper Class)
其内部维护的基本数据类型
Byte
private final byte value;
Short
private final short value;
Integer
private final int value;
Long
private final long value;
Float
private final float value;
Double
private final double value;
Boolean
private final boolean value;
Character
private final char value;
(不信的话,大家可以看看源代码
)
那么,对于属性是Wrapper Class的对象类型,虽然被浅克隆了,但是会不会有问题呢?请看下面的进一步测试
package tt;
import tt.vo.Person;
public class TestMain {
public static void main(String[] args) throws CloneNotSupportedException {
// initialize Person p
Person p = new Person();
p.setAge(18);
p.setHeight(162);
System.out.println("p:" + p);
Person pclone = p.clone();
System.out.println("pclone:" + pclone);
System.out.println("p.getHeight()==pclone.getHeight(): "+(p.getHeight()==pclone.getHeight()?"true":"false"));
System.out.println("-------------after set-------------------");
p.setAge(180); // 开辟了新的内存
p.setHeight(190); // 并没有修改原来的值!而是让height重新指向了190这个值的地址
System.out.println("p.getHeight()==pclone.getHeight(): "+(p.getHeight()==pclone.getHeight()?"true":"false"));
System.out.println("p:" + p);
System.out.println("pclone:" + pclone);
}
}
debug截图:
(ps: 每次debug时候,id所分配的号码会不一样)
通过debug可以发现:
- 在运行p.setHeight(190);之后,p.height所指向的对象id变成了新的(id=37)
- pclone.height还是指向原来的对象(id=26)
--------------------------------------------总结------------------------------------------------------------------
总结,一个自定义的Object:
- 在编写clone()方法的时候,默认的clone()方法行为,针对于Wrapper Class类型是浅克隆(只要是对象类型,都是浅克隆)
- 但是我们不需要担心,“p.height的值修改了,pclone.height也跟着修改” 的这种情况!
- 因为Wrapper Class类型,在赋值的时候,并没有修改原来的值!而是重新指向了一个新值的地址。有如下两种赋值方法:
- Integer height = new Integer(88);
- Integer height = 88;
- 所以:一个自定义的Object,针对于Wrapper Class类型,使用默认的clone()方法即可。