1. 程式人生 > 實用技巧 >Java中,String型別和包裝型別作為引數傳遞時,是屬於值傳遞還是引用傳遞呢?

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中方法引數的使用情況:

  1. 一個方法不能修改一個基本資料型別的引數(即數值型和布林型)
  2. 一個方法可以改變一個物件引數的狀態
  3. 一個方法不能讓物件引數引用一個新的物件

在方法中一個引用指向了一個新的物件,只在方法中生效,出了方法,原來的引用內容是怎麼樣還是怎麼樣:
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);