Lmxy1990 ' Blog

JAVA中的值类型,引用类型以及克隆

JAVA中的引用类型与值类型


1.引用类型
数组,集合,接口,类都是引用类型.

2.值类型
所有基本类型:int,short,long 及与之对应的Long,Integer,Double,
以及布尔类型boolead,Boolead 也包括Bigdecimal都属于值类型.

3.区别
这里不考虑实现,究其底层.只考虑Java中的二者之间的差异.
值类型:也就是改变原值,对其之前赋的变量的值没有影响.

1
2
3
4
5
6
BigDecimal d1 = BigDecimal.ONE ;
BigDecimal d2 = d1 ;
d1 = d1.add(BigDecimal.ONE) ;

System.out.println(d1);
System.out.println(d2);

结果如下:

1
2
3
4
5
6
2
3
4
2
3
4

引用类型:改变原值,对其之前使用=赋值的变量也会有影响.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int[] ar = {1,2,3} ;
int[] br = ar ;
ar[0] = 2 ;
ar[1] = 3 ;
ar[2] = 4 ;
for (int i = 0; i < ar.length; i++) {
int i1 = ar[i];
System.out.println(i1);
}

for (int i = 0; i < br.length; i++) {
int i1 = br[i];
System.out.println(i1);
}

结果如下:

1
2
2
1

4.浅析原理.
有一种说法是java没有值类型.其实角度不一样.从原理上来说确实没有.但从表象上来说是有的.因为在赋值运算的时候.遇到基本类型是新开辟内存空间.遇到引用类型是改变指针指向的地址.这区别与java对赋值运算的实现.

所以,java官方说基本类型是值类型.那就是说,赋值运算在对待基本类型的赋值与引用类型时候,会采用不同的方式去处理.这区别于C/C++.

这一点其实在对待Long Integer 类的赋值的时候,就可以看出来了.至于为什么基本类型赋值是新开辟,而引用类型是修改指针地址.这可能是因为所占对象大小,基本类型占用低,使用修改频繁.所以新增这样的对象所消耗内存少.而引用类型的内存消耗完全取决用用户的定义.故赋值采用的是改变指针的指向.而非new 对象.但是java提供一个克隆的方法.用于新开辟内存而非改变指针指向内存地址.

至于如果引用类型需要拷贝而不是改变指针的地址进行的赋值时候.可以采用克隆或者直接new 对象.然后进行对基本类型的赋值操作.遇到引用类型,就需要new/克隆去开辟新的内存空间.这样才能改变原对象的值,不会影响克隆的变量.

克隆


1.实现Cloneable接口
2.覆写Object的clone方法.
3.如果对象存在非基本类型,还需要修改覆写的方法.
eg: Java 自带的Calendar类覆写的clone方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public Object clone()
{
try {
Calendar other = (Calendar) super.clone();

other.fields = new int[FIELD_COUNT];
other.isSet = new boolean[FIELD_COUNT];
other.stamp = new int[FIELD_COUNT];
for (int i = 0; i < FIELD_COUNT; i++) {
other.fields[i] = fields[i];
other.stamp[i] = stamp[i];
other.isSet[i] = isSet[i];
}
other.zone = (TimeZone) zone.clone();
return other;
}
catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}

以上例子就是覆写clone方法.如果没有引用类型.那只需要调用超类的方法即可.

1
2
3
4
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}


End

坚持原创技术分享,您的支持将鼓励我继续创作!