Java中,String型別和包裝型別作為引數傳遞時,是屬於值傳遞還是引用傳遞呢?
Java中,String型別和包裝型別作為引數傳遞時,是屬於值傳遞還是引用傳遞呢?
原理知識:
如果引數型別是原始型別,那麼傳過來的就是這個引數的一個副本,也就是這個原始引數的值,這個跟之前所談的傳值是一樣的。如果在函式中改變了副本的 值不會改變原始的值.
如果引數型別是引用型別,那麼傳過來的就是這個引用引數的副本,這個副本存放的是引數的地址。如果在函式中沒有改變這個副本的地址,而是改變了地址中的 值,那麼在函式內的改變會影響到傳入的引數。
如果在函式中改變了副本的地址,如new一個,那麼副本就指向了一個新的地址,此時傳入的引數還是指向原來的 地址,所以不會改變引數的值。
String和包裝類是什麼型別傳遞這個問題,可能很多人都沒有去細想過,下面我就給點我自己的見解。
/**
*
* @author ZHOUMI2
*/
public class Test {
public static void test1(Integer num){
num = new Integer(5);
}
public static void test2(String str){
str.replace("1", "4");
}
public static void main(String[] args) {
Integer num = new Integer(1);
test1(num);
// 輸出結果為1
System.out.println(num.intValue());
String str = new String("123");
test2(str);
// 輸出結果為123
System.out.println(str);
}
}
分析:
上述程式很容易讓人誤以為String型別和包裝型別是值傳遞。
其實我們認真想一下:
String型別和包裝型別都是物件型別,所以必然是引用傳遞。
但是由於String類和包裝類都沒有提供value對應的setter方法,我們無法改變其內容,所以導致我們看起來好像是值傳遞。
以下討論Integer是引用傳遞還是值傳遞
轉自:http://www.tuicool.com/articles/AraaQbZ
論integer是地址傳遞還是值傳遞
Integer 作為傳參的時候是地址傳遞 , 可以參考如下例子,在程式剛啟動的時候把 Integer 的index 物件鎖住 ,並且呼叫了 wait方法,釋放了鎖的資源,等待notify,最後過了5秒鐘,等待testObject 呼叫notify 方法就繼續執行了。大家都知道鎖的物件和釋放的物件必須是同一個,否則會丟擲 java.lang.IllegalMonitorStateException 。由此可以證明 Integer作為引數傳遞的時候是地址傳遞,而非值傳遞。
public class IntegerSyn {
public static void main(String[] args) throws InterruptedException {
Integer index = 0;
TestObject a = new TestObject(index);
synchronized (index) {
new Thread(a).start();
index.wait();
}
System.out.println("end");
}
}
class TestObject implements Runnable {
private Integer index;
public TestObject(Integer index){
this.index = index;
}
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (index) {
index.notify();
}
}
}
那就會有人問了,為什麼執行如下程式碼的時候兩次的輸出結果是一樣的?
public static void main(String[] args) throws InterruptedException {
Integer index = 0;
System.out.println(index);
test(index);
System.out.println(index);
}
public static void test(Integer index){
index++;
}
理由很簡單,可以看到 Integer 類中final的value欄位,說明一旦integer類建立之後他的值就不能被修改,在 index++ 的時候Integer是建立一個新的類,所以這個第二次輸出的時候結果是一樣的!
private final int value;
- 1
總結一下java中方法引數的使用情況:
- 一個方法不能修改一個基本資料型別的引數(即數值型和布林型)
- 一個方法可以改變一個物件引數的狀態
- 一個方法不能讓物件引數引用一個新的物件
在方法中一個引用指向了一個新的物件,只在方法中生效,出了方法,原來的引用內容是怎麼樣還是怎麼樣:
Integer是不可變類,進入一個方法後,在裡面的值的改變不會影響方法外的引用
@Test
public void testInteger() {
Integer integer = new Integer(5);
testchange(integer);
//輸出結果還是5
System.out.println(integer);
}
private void testchange(Integer integer) {
integer =new Integer(8);
//這裡輸出結果是8
System.out.println("方法裡面的integer:"+integer);