引言
在计算机内存中,对象的存储类型和基本数据类型的存储方式是非常不同的,针对八种基本数据类型(比byte、short、int、long、char、float、double、boolean),其存储方式为直接存储在内存中,例如int a=8,那么在内存中存储的就是类似于00001000的数据,复制的时候例如b=a就是直接把这个值拷贝一份给a,下面介绍一下对象是怎么存储以及如何使用的。
引用语义
当使用对象时,变量是不会存储这个对象的,变量只保存着对这个对象的引用(说到底,引用也是一种数据结构),也就是说在内存中包括两部分:变量和对象,例如Point p = new Point(),p是变量,还有一个p指向的对象。以上就是引用类型,基本数据结构的是值类型。采用对象这种存储类型的是引用类型。
为什么要有引用语义?
众所周知,编程语言中史诗级的语言“C”中的变量采用的都是值类型,那么为什么java(可能其他的面向对象语言也是?)中却增加了一个“引用类型”呢?我想可能是有两方面考虑,如下:
(1)内存过大引起的效率问题:和基本数据类型不同,对象所占内存空间都比较大,如果像基本数据类型一样,拷贝时都整个拷贝,那么这会是一个很耗时且耗内存的过程,比如说一个String类型的对象,里面存储着一串拥有一万个字节的字符串,那么每次拷贝时都再复制一个一万字节的字符串,这个时间成本和内存成本是可想而知的,而引入引用语义以后,这时只需要复制一个指向这个字符串的变量,就可以对其进行操作。
(2)共享功能,因为每次复制的都是指向该对象的变量,那么多个变量都可以对同一个对象进行操作,实现了共享的功能。
为方法传递对象参数
首先要记住一点,在调用方法时,方法中的参数无论是值类型还是引用类型 ,都会进行一次拷贝,只不过值类型拷贝的是一个新的变量,而引用类型拷贝的是对于对象的一次引用,例如以下:
一个方法:
public static void manipulate(Point P)
{
p.translate(2,3);
}
然后创建一个新的对象的实例,调用这个方法:
Point test= new Point();
manipulate(P);
这个调用会对test指向的对象起作用吗,答案是肯定的,manipulate方法复制了test变量,这个变量指向的就是test指向的对象,因此肯定是起作用的。