Java面試中的值傳遞與引用傳遞

1、前言

Java是值傳遞的,對基本型變量而言的,傳遞的是該變量的一個副本,改變副本不影響原變量。對於對象型變量而言的,傳遞的是該對象地址的一個副本,,並非原對象自己 ,這裏也有人說是引用傳遞。因爲副本的地址和原對象地址一致,所以對副本的值進行操做時,會同步改變原對象值。html

可是一旦副本的地址被改變,副本的值的操做則不會影響原對象地址。(重點)java

2、常見例子

一、基本類型參數的值傳遞

public class Test {
    public static void main(String[] args) {
        int num = 0 ;
        changeNum(num);
        System.out.println("num="+num);
    }
 
    private static void changeNum(int num) {
        num = 1;
    }
}

最終輸出結果是:num=0面試

由於這裏 changeNum(num);語句中的num傳遞的是num的副本,也就是形參,因此當副本變爲1,對實參原對象不影響,原對象仍是num=0;數組

 

二、封裝類型參數

public class Test {
    public static void main(String[] args) {
        Product p = new Product();
        p.setProName("before");
        p.setNum(0);
        changeProduct(p);
        System.out.println("p.proName="+p.getProName());
        System.out.println("p.num="+p.getNum());
    }
 
    private static void changeProduct(Product p) {
        p.setProName("after");
        p.setNum(1);
    }
}
 
class Product {
    private int num;
    private String proName;
 
    public int getNum() {
        return num;
    }
 
    public void setNum(int num) {
        this.num = num;
    }
 
    public String getProName() {
        return proName;
    }
 
    public void setProName(String proName) {
        this.proName = proName;
    }
}

最終輸出結果是:p.proName=afterp.num=1函數

這裏咱們能夠看到 changeProduct(p); 該語句傳遞的是p內存中存儲的地址的副本,該地址就是new Product();的地址。在changeProduct方法中對p地址的副本指向的值進行操做,因爲副本地址和原地址同樣,因此至關於最終p地址指向的值也會發生變化。因此這裏的changeProduct方法能改變實參。this

 

可是存在如下特殊狀況,就是前言說的一旦副本的地址被改變。咱們再 changeProduct() 方法中添加一條語句;spa

private static void changeProduct(Product p) {
    p = new Product();//添加這條語句,至關於P的地址變成new Product()新對象的地址,不是主函數中的對象的地址
    p.setProName("after");
    p.setNum(1);
}

這裏添加的這條語句 改變了副本的地址,致使副本指向新對象的地址,所以變成對新對象的操做,不影響主函數中的原對象,最終輸出結果是:p.proName=beforep.num=0.net

 

三、容易忽略的特殊類型String

首先要清楚一點,這種說法不正確:String str = "java",這就至關於String str = new String("java"),這是建立一個新的String的過程,不僅僅是賦值的過程。code

public class Test {
    public static void main(String[] args) {
        String str = "ab";
        changeString(str);
        System.out.println("str="+str);
    }
 
    private static void changeString(String str) {
        str = "cd";
    }
}

猜猜這裏最終結果是什麼?htm

最終輸出結果是:str=ab 。(沒猜對的說明上面第二點還沒理解清楚)

解析:

str1 = "cd"
str2 = new String("cd");
System.out.println(str1 == str2); // false
說明str = "cd";不能被解釋爲以下:str = new String("cd");
這裏之因此最終顯示結果是「ad」,是由於main中的str的地址是常量池「ad」的地址,而在str = "cd"說明此時str的地址變成常量池「cd」的地址,地址改變,對實參原來的str無影響,因此最終輸出的仍是「ad」.

 

四、常見面試題

public class Example {
    String str = new String("good");
    char[] ch = { 'a', 'b', 'c' };
 
    public static void main(String args[]) {
        Example ex = new Example();
        ex.change(ex.str, ex.ch);
        System.out.print(ex.str + " and ");
        System.out.print(ex.ch);
    }
 
   public void change(String str, char ch[])      
   {
        str = "test ok";
        ch[0] = 'g';
    }
}

從以下4個選項選出最終輸出結果

A 、 good and abc
B 、 good and gbc
C 、 test ok and abc
D 、 test ok and gbc

正確答案: B

解析:

ex.str如第3點所說的,其傳遞的地址副本在change方法中被改變,所以不影響原地址的對象,因此ex.str不變;

ch數組是對象,數組的父類也是Object。傳遞的是數組地址的副本,所以在change中副本地址沒改變,至關於對原對象進行操做,因此ch數組的值發送變化。

 

 

參考資料:https://blog.csdn.net/party3/article/details/78648186

                https://www.cnblogs.com/boboooo/p/9066831.html

相關文章
相關標籤/搜索