今天要介绍一个概念,对象的克隆。本篇有一定难度,请先做好心理准备。看不懂的话可以多看两遍,还是不懂的话,可以在下方留的言,我会看情况进行修改和补充。
克隆,自然就是将对象重新复制一份,那为什么要用克隆呢?什么时候需要使用呢?先来看一个小栗子:
简单起见,我们这里用的是商品类的简单版本。
公共类商品{ 私人字符串标题; 私人双价格; 公共物品(字符串aTitle,双人力成本){ 标题=aTitle; 价格=人力成本; } 公共空间setPrice(双价格){ 这一点。价格=价格; } 公共空间setTitle(字符串标题){ 这一点。标题=标题; }//用于打印输出商品信息 公共空间print () { system . out。println(“标题:”+标题+“价格:”+价格); } }
然后我们来使用这个类。
公开课GoodsTest { 公共静态void main (String [] args) { 货物goodsA=新产品(“goodsA”, 20); 货物goodsB=goodsA; system . out。println(“在变化:”); goodsA.print (); goodsB.print (); goodsB.setTitle (“GoodsB”); goodsB.setPrice (50); system . out。println(“后变化:”); goodsA.print (); goodsB.print (); } }
我们创建了一个商品对象赋值给变量goodsA,然后又创建了一个商品变量,并把goodsA赋值给它,先调用产品的印刷方法输出这两个变量中的信息,然后调用商品类中的setTitle和setPrice方法来修改goodsB中的对象内容,再输出两个变量中的信息,下面是输出:
之前改变:
引用>
标题:GoodsA价格:20.0
标题:GoodsA价格:20.0
后改变:
标题:GoodsB价格:50.0
标题:GoodsB价格:50.0这里我们发现了灵异事,我们明明修改的是goodsB的内容,可是goodsA的内容也同样发生了改变,这究竟是为什么呢?别心急,且听我慢慢道来。
在爪哇语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int,双字节,布尔,char等简单数据类型,引用类型包括类,接口,数组等复杂类型。使用等号赋值都是进行值传递的,如将一个整数型变量赋值给另一个整数型变量,那么后者将存储前者的值,也就是变量中的整数值,对于基本类型如int,翻倍,char等是没有问题的,但是对于对象,则又是另一回事了,这里的goodsA和goodsB都是商品类对象的变量,但是它们并没有存储商品类对象的内容,而是存储了它的地址,也就相当于c++中的指针,如果对于指针不了解,那我就再举个栗子好了。我们之前举过一个栗子,把计算机比作是仓库管理员,内存比作是仓库,你要使用什么类型的变量,就需要先登记,然后管理员才会把东西给你,但如果是给你分配一座房子呢?这时候不是把房子搬起来放到登记簿粒,而是登记下房子的地址,这里的地址就是我们的类对象变量里记录的内容,所以,当我们把一个类对象变量赋值给另一个类对象变量,如goodsB=goodsA时,实际上只是把一个指向的对象地址赋值给了B,这样B也同样指向这个地址,所以这时候,goodsA和goodsB操作的是同一个对象。
所以,如果只是简单的赋值的话,之后对于goodsA和goodsB的操作都将影响同一个对象,这显然不是我们的本意。也许你还会问,直接再新的一个对象不就好了,确实如此,但有时候,如果我们需要保存一个goodsA的副本,那就不仅仅要新的一个对象,还需要进行一系列赋值操作才能将我们的新对象设置成跟goodsA对象一样,而且商品类越复杂,这个操作将会越繁琐,另外使用克隆方法还进行本地优化,效率上也会快很多,总而言之,就是简单粗暴。
那如何使用克隆呢?这里我们就要介绍我们牛逼哄哄的对象类了,所有的类都是对象类的子类,虽然我们并没有显式声明继承关系,但所有类都难逃它的魔掌,它有两个受保护的方法,其中一个就是克隆方法。
下面我来展示一波正确的骚操作:
//要使用克隆方法需要实现可克隆接口 公共类商品实现可克隆{ 私人字符串标题; 私人双价格; 公共物品(字符串aTitle,双人力成本){ 标题=aTitle; 价格=人力成本; } 公共空间setPrice(双价格){ 这一点。价格=价格; } 公共空间setTitle(字符串标题){ 这一点。标题=标题; } 公共空间print () { system . out。println(“标题:”+标题+“价格:”+价格); }//这里重载了接口的克隆方法 @Override 保护对象克隆(){ 货物g=零;//这里是异常处理的语句块,可以先不用了解,只要知道是这样使用就好,之后的文章中会有详细的介绍 尝试{ g=(商品)super.clone (); }捕捉(CloneNotSupportedException e) { System.out.println (e.toString ()); } 返回g; } }深入了解Java对象的克隆