一个网站建设多少钱,黑马程序员ppt课件,怎么优化推广自己的网站,网站建设 淘宝详情Java中的类根据赋值对象与被赋值对象是否共享对象的实际数据内存空间#xff0c;分为值型类和引用型类。 Java中将一个对象赋值给另一个对象时#xff0c;如果这个对象是值对象#xff08;所谓的值对象就是由值型类生成的对象#xff09;#xff0c;则这两个对象的实际数据… Java中的类根据赋值对象与被赋值对象是否共享对象的实际数据内存空间分为值型类和引用型类。 Java中将一个对象赋值给另一个对象时如果这个对象是值对象所谓的值对象就是由值型类生成的对象则这两个对象的实际数据存储空间是独立的各自保存数据的拷贝。因此分别修改这两个对象不会相互影响。如果这个对象是引用型对象所谓的引用型对象就是由引用型类生成的对象则这两个对象的实际数据存储空间是相同的两者共享实际数据存储区。因此分别修改这两个对象时实质上同时修改了另一个对象的数据。此时赋值前后看似有两个对象实际上同一个对象的两个不同引用而已两者所指向的对象数据区是相同的。 Java中的值型类包括表示基本数据类型的类例如IntegerLongDoubleFloatBooleanByteStringCharacter等除此之外的其他Java内置类以及所有的用户自定义类均属于引用型类。
先看一个小实验 Integer b1new Integer(123); //新建一个Integer类的对象 Integer b2b1; //将对象b1赋值给b2 b2456; //修改b的值 System.out.println(b1); //观察b1的值是否在被b2修改了。 以上处的运行结果是123表明Integer类型是值类型。 StuInfo s1,s2; //观察自定义类型StuInfo,其定义见稍后代码。 s1new StuInfo(18001,张一); //新建一个StuInfo类的对象 s2s1; //将对象s1赋值给s2 s2.setId(123); //修改s2的值 System.out.println(s1); //观察s1的值是否被s2修改了。 以上处的运行结果是“学号123 姓名张一”表明Integer类是引用型类。 明白了以上现象后在实际编程中应该要特别注意。例如在将对象添加到链表ArrayList后此对象和链表中对应的元素其实都是指向相同的对象数据存储空间也就是说此对象和链表中对应的元素是同一对象数据区的两个引用通过任何其中一个引用修改对象数据区实际上也修改了另一个引用的对象数据区因为两个引用指向同一对象数据区。 下面的程序展示了这种现象。
import java.util.ArrayList;
public class MyTest { public static void main(String[] args) { StuInfo s1,s2,s3; ArrayListStuInfo listnew ArrayListStuInfo(); s1new StuInfo(18001,张一); //新建3个对象s1,s2,s3 s2new StuInfo(18002,王二); s3new StuInfo(18003,赵三); list.add(s1); //将3个对象s1,s2,s3添加到链表list中 list.add(s2); list.add(s3); for(StuInfo e:list) //输出链表中的对象 System.out.println(e); System.out.println(); s1.setId(11); //修改对象s1,s2,s3的值 s1.setName(张十一); s2.setId(22); s2.setName(王二二); s3.setId(33); s3.setName(赵三三); for(StuInfo e:list) //观察链表list中的对象值是否发生变化。结果是确实发生了改变。 System.out.println(e); //也就是修改s1,s2,s3的值实际上修改了链表中对应元素的值。 System.out.println(); for(StuInfo e:list) //修改链表中对象的值 e.setId(e.getId()10); System.out.println(s1); //观察对象s1,s2,s3的值是否发生了改变。结果是确实发生了改变。 System.out.println(s2); //也就是修改链表中对应元素的值实际上修改了的对象s1,s2,s3的值。 System.out.println(s3); } }
//以下为StuInfo类的定义 class StuInfo{ private int id; private String name; public StuInfo(int id, String name) { super(); this.id id; this.name name; } public int getId() { return id; } public void setId(int id) { this.id id; } public String getName() { return name; } public void setName(String name) { this.name name; } Override public String toString() { return 学号id\t姓名name; } }
以上程序的运行结果
学号18001 姓名张一 学号18002 姓名王二 学号18003 姓名赵三
学号11 姓名张十一 学号22 姓名王二二 学号33 姓名赵三三
学号21 姓名张十一 学号32 姓名王二二 学号43 姓名赵三三 如果实际编程中需要避免这种两个对象引用同一对象数据区的情形发生解决办法有2个。 办法1覆盖override该类的clone()方法在该clone()方法中先new一个新对象然后将对象的所有数据成员分别一一赋值给新对象最后返回新对象那么在原来给对象赋值的操作改为调用clone()方法。例如,将s2s1语句改为s2s1.clone()即可。 办法2实现方法1中clone()函数的方式设计一个构造函数该构造函数的参数是同类对象。这种构造函数有时称为“拷贝构造函数”。