引用:
声明Circle变量时,编译器不生成代码来分配足以容纳一个Circle的内存块,相反,它唯一做的事情,就是分配一个小块内存,其中刚好可以容纳一个地址…以后,Circle实际占用内存块的地址会填充到这里 该地址称为对内存块的引用 ,Circle对象实际占用的内存是在使用new关键字创建对象时分配的 //
Circle c;
c = new Circle();
以上代码在内存中的变化步骤:
1.在栈中分配出一小块内存,它刚够存储一个引用(一个内存地址),只是暂时不进行初始化(它是为Circle类型的变量c准备的).
2.接着 要从堆中分配一个足够大的内存区域来容纳一个Circle对象. 这正是new关键字所执行的操作:它运行Circle构造器,将这个原始的堆内存转换成Circle对象, 对这个Circle对象的引用将存储到变量c中
ps: 只复制引用成为浅拷贝, 能够复制引用的对象成为深拷贝
装箱和拆箱
object类型 为所有类的基类, object类型的变量能够引用任何对象
将数据项从栈自动复制到堆的行为称为装箱
Circle c;
c = new Circle(42);
object o;
o = c;
/~~~~~~~~~分割~~~~~~~~~/
将数据项从栈自动复制到堆的行为称为装箱
int i = 42;
object o = i;
// 修改变量i的原始值,o所引用的堆上的值不会改变,类似地,修改堆上的值,变量的原始值也不会改变
/~~~~~~~~~分割~~~~~~~~~/
为了访问已装箱的值,必须进行强制类型转换,简称转型
int i = 42;
object o = i; // 装箱
i = (int)o // 成功编译
编译器发现了指定的类型int,所以会在运行时生成代码检查o实际引用的是什么,它可能引用任何东西 不能因为你在转型说o引用的是int 它就真的引用一个int 如果说o真的引用一个已装箱的int 转型就会成功执行,编译器生成的代码会从装箱的int中提取出值,这个过程称为拆箱
PS:指针是特殊变量,其中容纳着内存(堆或栈)中的一个数据项的地址(或者说对这个数据项的引用)