日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java编程中值得注意的对象引用现象

發布時間:2023/12/10 java 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java编程中值得注意的对象引用现象 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? Java中的類根據賦值對象與被賦值對象是否共享對象的實際數據內存空間,分為值型類引用型類

? ? ? ? Java中將一個對象賦值給另一個對象時,如果這個對象是值對象(所謂的值對象就是由值型類生成的對象),則這兩個對象的實際數據存儲空間是獨立的,各自保存數據的拷貝。因此分別修改這兩個對象不會相互影響。如果這個對象是引用型對象(所謂的引用型對象就是由引用型類生成的對象),則這兩個對象的實際數據存儲空間是相同的,兩者共享實際數據存儲區。因此,分別修改這兩個對象時,實質上同時修改了另一個對象的數據。此時,賦值前后看似有兩個對象,實際上同一個對象的兩個不同引用而已,兩者所指向的對象數據區是相同的。

? ? ? ? Java中的值型類包括表示基本數據類型的類(例如Integer,Long,Double,Float,Boolean,Byte,String,Character等),除此之外的其他Java內置類以及所有的用戶自定義類均屬于引用型類

先看一個小實驗:

? ? ? ? Integer b1=new Integer(123);? //新建一個Integer類的對象
?? ??? ?Integer b2=b1; //將對象b1賦值給b2
?? ??? ?b2=456; //修改b的值
?? ??? ?System.out.println(b1); //觀察b1的值是否在被b2修改了。??以上處的運行結果是123,表明Integer類型是值類型。
?? ??? ?StuInfo s1,s2;?? ??//觀察自定義類型StuInfo,其定義見稍后代碼。? ?? ? ? ??
?? ??? ?s1=new StuInfo(18001,"張一"); //新建一個StuInfo類的對象
? ? ? ? s2=s1; //將對象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;?? ??? ?
?? ??? ?ArrayList<StuInfo> list=new ArrayList<StuInfo>();?? ??? ?
?? ??? ?
?? ??? ?s1=new StuInfo(18001,"張一");?//新建3個對象s1,s2,s3? ? ? ?? ?
?? ??? ?s2=new StuInfo(18002,"王二");? ? ? ?
?? ??? ?s3=new 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()方法。例如,將s2=s1語句改為s2=s1.clone(),即可。

? ? 辦法2:實現方法1中clone()函數的方式設計一個構造函數,該構造函數的參數是同類對象。這種構造函數有時稱為“拷貝構造函數”。

總結

以上是生活随笔為你收集整理的Java编程中值得注意的对象引用现象的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。