面試常考基礎(chǔ),Java傳遞方式--值傳遞
前言
這是一篇很基礎(chǔ)的文章,有一天我突然想到Java中只有值傳遞,但是為什么在傳遞對象的時(shí)候,里面的值修改后,實(shí)參也會(huì)被修改,我就特意去了解了一下這些相關(guān)的知識。這一學(xué),我發(fā)現(xiàn)我之前的一些了解是錯(cuò)誤的,不只是是對Java傳遞參數(shù)理解有問題,對C++中這傳遞也是有問題的。因此我覺得我應(yīng)該特地寫一篇隨筆,幫我理解,畢竟感覺真正的弄懂,是能夠幫助別人理解。
正文
值傳遞
簡單的基本類型
關(guān)于值傳遞基本類型我就不過多敘述了,感覺有點(diǎn)像水字?jǐn)?shù)一樣。
就簡單舉個(gè)例子過一下
public class Main {
public static void change(int a){
a = 2;
}
public static void main(String[] args) {
int a = 1;
change(a);
System.out.println(a);
}
}
運(yùn)行截圖:

基本的數(shù)據(jù)類型都是這樣的情況
傳遞引用類型
接下來來傳遞引用類型
現(xiàn)在說一下前言中說我在C++關(guān)于傳遞的錯(cuò)誤理解
我一直以為,C++中的引用傳遞,傳遞的參數(shù)與實(shí)參指向同一個(gè)對象(這是對的),因此傳遞過去實(shí)際是實(shí)參的地址,后面我才發(fā)現(xiàn)我理解錯(cuò)了,實(shí)際形參就直接理解為就是實(shí)參的一個(gè)別名。
接下來說說我另一個(gè)理解錯(cuò)誤的地方(這部分結(jié)合值傳遞引用類型講解)
我過去的理解,值傳遞是不可能能夠改變實(shí)參的,在Java中,我又發(fā)現(xiàn)好像可以改變耶,我就以為是不是我記錯(cuò)了,Java中的傳遞方式也是有兩種,除了值傳遞,還有引用傳遞,我還以為我記錯(cuò)了,我特意上網(wǎng)查了一下,確實(shí)沒有,我也特意弄懂了這一部分。
下面我將通過例子進(jìn)行講解
class Student {
public int id;
public String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student{id=" + id + ", name='" + name + "'}";
}
}
public class Main {
public static void change1(Student student) {
student.id = 2;
}
public static void change2(Student student) {
student=new Student(2,"Bob");
}
public static void main(String[] args) {
Student student1 = new Student(1, "Alice");
Student student2 = new Student(1, "Alice");
System.out.println("student1改變前 " + student1);
System.out.println("student2改變前 " + student2);
change1(student1);
change2(student2);
System.out.println("根據(jù)change1方法改變后 " + student1);
System.out.println("根據(jù)change2方法改變后 " + student2);
}
}
在例子中我們定義了Student類用充當(dāng)引用對象,方法change1相當(dāng)于setter方法,改變形參對象內(nèi)屬性值;方法change2則是使更換指向?qū)ο蟆?/p>
運(yùn)行截圖:

最后方法change1根據(jù)使得實(shí)參對象內(nèi)屬性值發(fā)生改變,而方法change2卻沒用使得實(shí)參更換指向?qū)ο蟆?/p>
原因講解:
change1(student1)
形參 student1 得到 假設(shè)地址為0xAAA 的拷貝。
student.id = 2; 是通過這份拷貝里的地址找到原對象,把 id 改成 2。
原對象確實(shí)被改了,因此 student1 打印出 Student{id=2, name='Alice'}。
change2(student2)
形參 student2 得到 假設(shè)地址為0xBBB 的拷貝。(因?yàn)槭莕ew Student()創(chuàng)建,執(zhí)行兩個(gè)完全獨(dú)立的對象)
student = new Student(2,"Bob"); 只是 把這份拷貝里的地址改成了新對象 0xCCC,原來的 student2 仍指向 0xBBB,毫無變化。
所以 student2 打印依舊是 Student{id=1, name='Alice'}。
對應(yīng)值傳遞引用對象,更換指向?qū)ο螅雍芏啵锩嬗泻芏嗪茈[晦的,如對String賦值,由于String是不可變,用final修飾,看向在實(shí)現(xiàn)String更換值了,實(shí)際是更換了指向?qū)ο螅贿€有Integer的自動(dòng)裝箱,這些例子我參考了一下這篇文章(https://blog.csdn.net/yiridancan/article/details/149813906)
結(jié)論
- Java 中進(jìn)行值傳遞,方法收到的永遠(yuǎn)是實(shí)參的一份拷貝,也可以說是副本,在傳遞基本類型時(shí),是傳遞真正的數(shù),對這份拷貝本身做任何重新賦值都不會(huì)影響原來的變量;在傳遞引用類型時(shí),是傳遞的是對象地址的副本,而但通過拷貝里保存的對象地址去改對象內(nèi)部字段是可以的。*

浙公網(wǎng)安備 33010602011771號