一个自定义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()方法即可。