天天看點

牛客刷題-Java專項練習(2022-4-1)

📢 本文章按照牛客網每日一練上的10道題目上做錯的習題來記錄錯題,并分享解析。

👤 公衆号:恩故事還在繼續

打卡時間 📅 2022-4-1

題目類型:基礎概念

題目難易程度: ⭐️⭐️⭐️

寫作耗時 🕑 : 2 h 30 min

題目數量:10    答對題目數:4   準确率:40%

1️⃣ 指出下列程式運作的結果(B)

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';
    }
}      
A. good and  abc
B. good and gbc
C. test ok and abc
D. test      

✏️ 解析

解決這道題目之前我們需要掌握以下幾個知識點
1. Java 值傳遞
2. Java 引用傳遞
3. JVM 常識      

🔥 值傳遞

值傳遞(pass by value)是指在調用函數時将實際參數 複制 一份傳遞到函數中,而并不是将這個值直接傳遞給函數.

🔥 引用傳遞

引用傳遞(pass by reference)是指在調用函數時将實際參數的位址直接傳遞到函數中,而傳遞過來的位址還是與之前的位址指向同一個值,那麼要是修改了 這個參數,就會影響這個值的改變

🅰️ 下面看幾個例子來初步了解下這2個概念

傳遞類型為基本類型 int
public static void main(String[] args) {
        int value = 10;
        setValue(value);
        System.out.println("調用後:"+ value);
    }
    public static void setValue(int value) {
        value = 2 * value;
        System.out.println("調用時:" + value);
    }      
輸出結果為:
調用時:20
調用後:10      

📔 小結

value 的值并沒有因為調用了 setValue()方法,而發生改變,是以我們可得: Java 中的基本類型 是采用值傳遞的方式的,采用值傳遞不會改變原來值
傳遞類型為引用類型: String
public static void main(String[] args) {
        String value = "hello";
        setValue(value);
        System.out.println("調用後:"+ value);
    }
    public static void setValue(String value) {
        value = value + "123";
        System.out.println("調用時:" + value);
    }      
輸出結果:
調用時:hello123
調用後:hello      

📔 小結

value 的值并沒有因為調用了 setValue()方法,而發生改變,是以我們可得: Java 中的引用類型 是采用值傳遞的方式的,采用值傳遞不會改變原來值

值傳遞 🆚 引用傳遞

這裡總結下這兩者的一些差別:
1. 對于八種基本類型的包裝類 + String 他們都是不可變對象,是以也會以值傳遞的方式傳入方法内部,在方法内部改變他們額數值不會影響原來的值。
2. 對于方法内傳入的是對象比如:數組, 在方法内對數組的值進行改變的話會影響原數組的值。      

🔗 ​​參考連連結: Java中的值傳遞&&引用傳遞​​​    ​​終于弄懂了:Java 中到底有沒有引用傳遞?​​

🅱️ JVM 裡的一點小概念

通過下面這個例子來了解我們建立對象或者變量在JVM裡的一些不同
String str1 = "java"; //直接指派而不是使用new關鍵字給字元串初始化,在編譯時就将String對象放進字元串常量池中
String str2 = new String("java"); // 使用new關鍵字初始化字元串時,是在堆棧區存放變量名和内容
String s = str1+str2;      

📔 小結

直接指派而不是使用new關鍵字給字元串初始化,在編譯時就将String對象放進字元串常量池中;使用new關鍵字初始化字元串時,是在堆棧區存放變量名和内容;字元串的拼接操作在程式運作時,才在堆中建立對象。一般,可以認為使用"=="比較的是引用,equals比較的是内容。
回到我們題目來,根據上面的概念我們可以知道對于: String str = new String("good");
我們将str 傳入change() 中然後對str進行指派由于String是引用類型是以按照值傳遞的方式進行傳參,我們在
change()方法類對str指派并不影響原來str的值。
但是我個人的一個了解是:new String() 是str指向堆的,而 str = "test ok";是指向常量池的,是以後面改變不影響前面原來的值。
對于ch數組,傳入的是對象,是以将ch傳入change()      

📝 總結

這篇文章算是👨重溫Java基礎的第五天, 雖然隻記錄了一個題目,但是裡面涉及到的原理真的好多,了解起來也耗時間,何況還要寫出來,再接再厲吧。