java 函式引數的傳遞方式說明(string、 引用型別、基本型別)
程式碼示例:
執行結果:public class TimerTest_main { String obj="Object"; public static void main(String[] agrs){ TimerTest_main obj_demo = new TimerTest_main(); String str =new String( "string"); int intType=0; obj_demo.getTest(obj_demo,str,intType); System.out.println("obj="+obj_demo.obj); System.out.println("str="+str); System.out.println("intType="+ intType); } public void getTest(TimerTest_main obj,String str,Integer intType){ obj.obj="ObjectChange"; str="stringChange"; intType=90; } }
obj=ObjectChange
str=string
intType=0
從執行結結果可以看出呼叫函式外部的 string 型別(引用型別)的沒有被修改 int型別(基本型別)沒有被修改 ,TimerTest_main(引用型別)的屬性被成功修改
1、從結果來看對於基本型別資料來說 呼叫函式屬於 “值傳遞” ,即方法操作的是引數變數(也就是原型變數的一個值的拷貝)改變的也只是原型變數的一個拷貝而已,而非變數本身。所以變數原型並不會隨之改變。
2、從TimerTest_main引用型別輸出的結果來看 引用型別應該屬於“引用傳遞”,也叫做傳地址,即方法操作引數變數時是拷貝了變數的引用,注意傳遞給方法的引數為變數的引用,其實也就是指標,而後通過這個引用找到變數(在這裡是物件)的真正地址,並對其進行操作就會改變原有值
3、為什麼string型別也是引用型別為什麼函式呼叫沒有改變外部的原型的值呢?
這主要是由於string內部儲存值方式的原因 string是通過一個finalchar[]陣列進行儲存的 由於final型別的陣列值不能夠改變,所以在外部呼叫函式時將string地址的引用進行傳遞給函式的引數,函式內部再修改這個引用時,由於finalchar[] 不可修改,所以在再給變數賦值新值時都會重新建立一個string例項(這個新建立的string例項所指向的地址和外部string變數所指向的地址是不同的所以改變不了外部的變數)另外一個點說明因為final
String 物件是不可變的,所以可以共享 也就是說 String op="abc" 和 String op1="abc" 指向的是同一個引用物件(字串是常量;它們的值在建立之後不能更改---jdk Api)
如圖所示最終外部變數A指向的地址和方法B中A指向的地址不同
java中字串存在常量池中。 java的記憶體分為堆,棧,方法區(包括常量池)。 java中字串存改在常量池中。 方法區中主要存在類結構,靜態變數。方法區又包含常量池,常量池儲存字串常量。
變數:記憶體地址不變,記憶體值可以修改
常量:記憶體值不能改變,只能通過更改引用值來指向另一塊記憶體String類的概念
String類是用於字串相關操作的一個類。
類包括成員變數和方法。
(1)String類有一個特殊的成員變數,儲存著常量池中某個字串的記憶體地址,也可以理解為一個指標。
(2)String類有一些方法,如indexOf(),charAt()。String類沒有對字串進行修改的方法。
雖然String類沒有修改字串的方法,但保留字串地址的成員變數是可以修改的,也就是說String類的物件可以指向另外的字串。
string 兩種例項化方式解析
String str= "abc" 建立方式
建立物件的過程
1 首先在常量池中查詢是否存在內容為"abc"字串物件
2 如果不存在則在常量池中建立"abc",並讓str引用該物件
3 如果存在則直接讓str引用該物件
String str= new String("abc")建立方式建立物件的過程
1 首先在堆中(不是常量池)建立一個指定的物件,並讓str引用指向該物件。
2 在字串常量池中檢視,是否存在內容為"abc"字串物件
3 若存在,則將new出來的字串物件與字串常量池中的物件聯絡起來(即讓那個特殊的成員變數value的指標指向它)
4 若不存在,則在字串常量池中建立一個內容為"abc"的字串物件,並將堆中的物件與之聯絡起來。(有可能此時常量池中的"abc"已經被回收,所以要先建立一個內容 為"abc"的字串物件)