一般引用類型(reference type)指向一個對象,不是原始值,指向對象的變量是引用變量。在 Java 里面除去基本數據類型的其它類型都是引用數據類型。Java 程序運行時,會為引用類型分配一定量的存儲空間并解釋該存儲空間的內容。示例如下:
創新互聯公司從2013年成立,是專業互聯網技術服務公司,擁有項目網站建設、成都網站建設網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元卡若做網站,已為上家服務,為卡若各地企業和個人服務,聯系電話:028-86922220public class MyDate{
private int day=8;
private int month=8;
private int year=2008;
public MyDate(int day, int month, int year){…}
public void print(){…}
}
public class TestMyDate{
public static void main(String args[]){
MyDate today = new MyDate(23,7,2008);//這個 today 變量就是一個引用類型的變量
}
}
2:引用類型的賦值
在 Java 編程語言中,用類的一個類型聲明的變量被指定為引用類型,這是因為它正在引用一個非原始類型,這對賦值具有重要的意義。請看下列代碼片段:
int x = 7;
int y = x;
String s = “Hello”;
String t = s;
四個變量被創建:兩個原始類型 int 和兩個引用類型 String。x 的值是 7,而這個值被復制到 y; x 和 y 是兩個獨立的變量且其中任何一個的進一步的變化都不對另外一個構成影響。 至于變量 s 和 t,只有一個 String 對象存在, 它包含了文本“Hello” ,s 和 t 均引用這個單一的對象。將變量 t 重新定義為:t=”World”; 則新的對象 World 被創建,而 t 引用這個對象。上述過程被描述如下
3:按值傳遞還是按引用傳遞這個在 Java 里面是經常被提起的問題,也有一些爭論,似乎最后還有一個所謂的結論:“在 Java 里面參數傳遞都是按值傳遞” 。事實上,這很容易讓人迷惑,下面先分別看看什么是按值傳遞, 什么是按引用傳遞, 只要能正確理解, 至于稱作按什么傳遞就不是個大問題了。
3.1:按值傳遞是什么指的是在方法調用時,傳遞的參數是按值的拷貝傳遞。示例如下:
public class TempTest {
private void test1(int a){
//做點事情
}
public static void main(String[] args) {
TempTest t = new TempTest();
int a = 3;
t.test1(a);//這里傳遞的參數a就是按值傳遞
}
}
按值傳遞重要特點:傳遞的是值的拷貝,也就是說傳遞后就互不相關了。
示例如下:
public class TempTest {
private void test1(int a){
a = 5;
System.out.println("test1方法中的a==="+a);
}
public static void main(String[] args) {
TempTest t = new TempTest();
int a = 3;
t.test1(a);//傳遞后,test1方法對變量值的改變不影響這里的a
System.out.println("main方法中的a==="+a);
}
}
運行結果是:
test1方法中的a===5
main 方法中的 a===3
3.2:按引用傳遞是什么
指的是在方法調用時,傳遞的參數是按引用進行傳遞,其實傳遞的引用的地址,也就是變量所對應的內存空間的地址。
示例如下:
public class TempTest {
private void test1(A a){
}
public static void main(String[] args) {
TempTest t = new TempTest();
A a = new A();
t.test1(a); //這里傳遞的參數a就是按引用傳遞
}
}
class A{
public int age = 0;
}
3.3:按引用傳遞的重要特點傳遞的是值的引用,也就是說傳遞前和傳遞后都指向同一個引用(也就是同一個內存空間) 。
示例如下:
第1行 public class TempTest {
第2行 private void test1(A a){
第3行
a.age = 20;
第4行
System.out.println("test1方法中的age="+a.age);
第5行 }
第6行 public static void main(String[] args) {
第7行
TempTest t = new TempTest();
第8行
A a = new A();
第9行
a.age = 10;
第10行
t.test1(a);
第11行
System.out.println("main方法中的age="+a.age);
第12行 }
第13行 }
第14行 class A{
第15行 public int age = 0;
第 16 行 }
運行結果如下:
test1方法中的age=20
main 方法中的 age=20
3.4:理解按引用傳遞的過程——內存分配示意圖要想正確理解按引用傳遞的過程, 就必須學會理解內存分配的過程, 內存分配示意圖可以輔助我們去理解這個過程。
用上面的例子來進行分析:
(1) :運行開始,運行第 8 行,創建了一個 A 的實例,內存分配示意如下:
main 方法中的變量 a
(2) :運行第 9 行,是修改 A 實例里面的 age 的值,運行后內存分配示意如下:
main 方法中的變量 a
這是一個 A 的實例
此時 age = 0;
這是一個 A 的實例
此時 age = 10;
(3) :運行第 10 行,是把 main 方法中的變量 a 所引用的內存空間地址,按引用傳遞給 test1
方法中的 a 變量。請注意:這兩個 a 變量是完全不同的,不要被名稱相同所蒙蔽。
內存分配示意如下:
main 方法中的變量 a 賦值給 (按引用傳遞) test1 方法中的變量 a 由于是按引用傳遞, 也就是傳遞的是內存空間的地址, 所以傳遞完成后形成的新的內存示意圖如下:
main 方法中的變量 a test1 方法中的變量 a 也就是說:是兩個變量都指向同一個空間。
(4) :運行第 3 行,為 test1 方法中的變量 a 指向的 A 實例的 age 進行賦值,完成后形成的新的內存示意圖如下:
main 方法中的變量 a test1 方法中的變量 a 此時 A 實例的 age 值的變化是由 test1 方法引起的
(5) :運行第4行,根據此時的內存示意圖,輸出test1方法中的age=20
(6) :運行第 11 行,根據此時的內存示意圖,輸出 main 方法中的 age=20
3.5:對上述例子的改變 理解了上面的例子,可能有人會問,那么能不能讓按照引用傳遞的值,相互不影響呢?就是 test1 方法里面的修改不影響到 main 方法里面呢?
方法是在 test1 方法里面新 new 一個實例就可以了。改變成下面的例子,其中第 3 行為
新加的:
第1行 public class TempTest {
第2行 private void test1(A a){
第3行
a = new A();//新加的一行
第4行
a.age = 20;
第5行
System.out.println("test1方法中的age="+a.age);
第6行 }
第7行 public static void main(String[] args) {
這是一個 A 的實例
此時 age = 10;
這是一個 A 的實例
此時 age = 10;
這是一個 A 的實例
此時 age = 20;
第8行
TempTest t = new TempTest();
第9行
A a = new A();
第10行
a.age = 10;
第11行
t.test1(a);
第12行
System.out.println("main方法中的age="+a.age);
第13行 }
第14行}
第15行class A{
第16行 public int age = 0;
第 17 行}
運行結果為:
test1方法中的age=20
main 方法中的 age=10
為什么這次的運行結果和前面的例子不一樣呢,還是使用內存示意圖來理解一下
3.6:再次理解按引用傳遞
(1) :運行開始,運行第 9 行,創建了一個 A 的實例,內存分配示意如下:
main 方法中的變量 a
(2) :運行第 10 行,是修改 A 實例里面的 age 的值,運行后內存分配示意如下:
main 方法中的變量 a
(3) :運行第 11 行,是把 main 方法中的變量 a 所引用的內存空間地址,按引用傳遞給 test1方法中的 a 變量。請注意:這兩個 a 變量是完全不同的,不要被名稱相同所蒙蔽。
內存分配示意如下:
main 方法中的變量 a賦值給 (按引用傳遞)test1 方法中的變量 a
由于是按引用傳遞, 也就是傳遞的是內存空間的地址, 所以傳遞完成后形成的新的內存這是一個 A 的實例
此時 age = 10;
示意圖如下:
main 方法中的變量 a
test1 方法中的變量 a
也就是說:是兩個變量都指向同一個空間。
(4) :運行第 3 行,為 test1 方法中的變量 a 重新生成了新的 A 實例的,完成后形成的新的
內存示意圖如下:
main 方法中的變量 a
test1 方法中的變量 a
(5) :運行第 4 行,為 test1 方法中的變量 a 指向的新的 A 實例的 age 進行賦值,完成后形成的新的內存示意圖如下:
main 方法中的變量 a
test1 方法中的變量 a
注意:這個時候 test1 方法中的變量 a 的 age 被改變,而 main 方法中的是沒有改變的。
(6) :運行第5行,根據此時的內存示意圖,輸出test1方法中的age=20
(7) :運行第 12 行,根據此時的內存示意圖,輸出 main 方法中的 age=10
3.7:說明
(1) : “在 Java 里面參數傳遞都是按值傳遞”這句話的意思是:按值傳遞是傳遞的值的
拷貝,按引用傳遞其實傳遞的是引用的地址值,所以統稱按值傳遞。
(2) :在 Java 里面只有基本類型和按照下面這種定義方式的 String 是按值傳遞,其它
的都是按引用傳遞。就是直接使用雙引號定義字符串方式:String str = “Java 私塾”;
網站題目:三、引用類型-創新互聯
網頁網址:http://vcdvsql.cn/article14/hdjge.html
成都網站建設公司_創新互聯,為您提供用戶體驗、虛擬主機、外貿網站建設、微信公眾號、品牌網站設計、外貿建站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯