-
1 # 二令先森啊
-
2 # 但求無Bug
嚴格來說,Java只有值傳遞,沒有引用傳遞一說。那麼為什麼會有這種說法?
首先來說說Java的資料型別。Java的資料型別分為基本資料型別和引用資料型別。
基本資料型別大致分為:byte、short、int、long四種整數型,float和double兩種浮點型(也就是小說), 一種char字元型加一種boolean型別。而引用資料型別則是除這八種資料型別之外的所有資料型別。
那麼基本資料型別和引用資料型別區別在哪呢?其區別在於對應資料型別的物件在記憶體中的位置不同。
jvm記憶體分為:方法棧區、堆記憶體區、本地方法棧、方法區以及程式計數器等。其中,我們常提到的兩塊記憶體是堆記憶體區和方法棧區。
接下來我還得說說啥叫變數。在Java中變數就是一個合法字元,用來儲存某個物件對應的地址值。變數的值都是儲存在方法棧區,不論是基本資料型別還是引用資料型別。只不過資料型別不同,該變數所指向的真正物件的值所儲存區域不同。
對於基本資料型別來說,其值是直接放在方法棧區中,可以認為變數值就是其物件所對應的值。因此,當你進行方法呼叫時,是將方法棧中的值直接進行了傳遞。
但是對於引用資料型別來說則不是。引用資料型別存在兩種值:真正值和引用值,其中引用值就是變數值。因為Java不允許直接訪問堆區內容,所以我們只能透過方法棧區的變數值來間接訪問堆中的真正值。因此,當進行方法呼叫時,實參會將其對應的引用值進行傳遞。究其本質,引用資料型別還是值傳遞,只不過傳遞的是引用值罷了。所以這就導致某些人說是引用傳遞。
當然,有時候說引用傳遞也沒錯,只不過我覺得不夠嚴謹罷了。
-
3 # 程式猿開發日記
Java中只有值傳遞。
當我們將一個變數當成引數傳遞給某個方法的時候,無論該變數是基本資料型別,還是引用型別,傳遞的並非變數本身,而是變數的複製值,這也是為什麼說Java只有值傳遞。
那麼為什麼會有引用傳遞這一說呢?
這是因為當傳遞的變數資料型別是引用型別的時候,變數儲存的並不是真實的值,而是值的引用(可以理解為指標),我們複製一份出來當引數的時候,它儲存的仍然是值的引用,當我們對引用的值進行修改的時候,他的影響是全域性的,也就是原值會收到影響。但是基本型別不同,變數本身儲存的值放在變數記憶體(棧)裡面,不存在引用,所以修改複製變數的值,對原值沒有影響。
所以說Java只有值傳遞,但是傳遞的型別不同,一些相同的操作影響會不同,所以有時我們會說引用傳遞。
-
4 # 自學JAVA
在Java中確實是只有值傳遞,沒有引用傳遞的,在知道什麼是值傳遞什麼是引用傳遞的時候我也要知道什麼是值型別,什麼是引用型別;
值型別在這裡我就不用棧,堆,方法區這些東西來解釋, 用最樸素的方式解釋解釋。
看看下面的圖就知道什麼是值型別了:
可以看到,值型別的宣告出來在記憶體地址中是直接開闢空間儲存值的,那麼不同的變數會分配不同的記憶體空間。所以改變這個變數中的值對其它變數是沒有影響的。我們使用過的內容中,八大基本資料型別都是值型別,列舉也是值型別的。
引用型別引用型別透過下面圖片示例來看看:
宣告一個物件,也就是引用型別在記憶體地址中存的不是值,而是指向實際物件的地址值。而它具體的物件是存在另外一個記憶體地址中。所以如果你把當前物件賦值給另外一個物件,它們操作的就是同一個地址的物件,所以相互之間會有影響的。
我們瞭解到了兩種資料的型別的工作原理,下面我們來看看什麼是值傳遞什麼是引用傳遞
值傳遞值傳遞的傳遞方式就是直接把宣告的記憶體地址中的值傳遞到方法中做運算,值傳遞對應的又可以用值資料型別做為引數,引用資料型別做引數
值型別做值傳遞
透過示例程式碼我們來理解
定義方法:
public void show(int a){//方法體}
呼叫方法:
int a=10;
物件名.show(a);
這個時候只會把實參a變數的值10傳遞到方法中做運算
引用型別做值傳遞也是透過示例程式碼來做理解
定義方法:
public void show(Student stu){//方法體}
呼叫方法:
Student stu=new Student();
物件名.show(stu);
引用型別會把物件的記憶體地址傳到方法中做運算,因為我們上面講了引用型別在記憶體中存的是地址值。所以引用型別做為引數傳遞到方法中做運算是會對實參stu有影響的。
引用傳遞引用傳遞在是需要在定義方法的形參中和呼叫方法的實參中加一些特殊符號的,所以在Java中是沒有所謂的引用傳遞的,那我就拿c#中的引用傳遞做示例來說說什麼是引用傳遞。同樣的引用傳遞是用不同的資料型別做為引數。引用傳遞實際就是把變數本身傳遞到方法中做運算。
值型別做引用傳遞
也是透過示例程式碼來理解,這裡我用c#來做示例,值型別做引用傳遞
定義方法:
public void show(ref int a){}
呼叫方法:
int a=20;
物件名.show(ref a);
可以看到在c#中引用傳遞需要在形參和實參上都加上ref特殊符號,那麼根據引用傳遞的概念這裡實參變數a傳遞到方法中做運算會對實參有影響。
引用型別做引用傳遞其實引用型別做引用傳遞和值傳遞沒有多大的區別,因為不管怎麼你是做那種傳遞方式傳進來的都是同一個地址值,也就是同一個物件。最後對實參都會有影響。
定義方法:
public void show(ref Student stu){//方法體}
呼叫方法:
Student stu=new Student();
物件名.show(ref stu);
總結:在Java中所謂的引用傳遞真的不存在,看到下面很多答主答的內容都是在說引用型別作為引數傳遞。總體來說資料型別總體兩大類,值型別和引用型別。傳遞方式分為兩種,值傳遞和引用傳遞。
-
5 # 山東中公優就業
是按值傳遞。Java 語言的引數傳遞只有按值傳遞。當一個例項物件作為引數被傳遞到方法中時,引數的值就是該物件的引用的一個副本。指向同一個物件,物件的內容可以在被呼叫的方法內改變,但物件的引用(不是引用的副本) 是永遠不會改變的。
Java的引數傳遞,不管是基本資料型別還是引用型別的引數,都是按值傳遞,沒有按引用傳遞!
回覆列表
Java只有值傳遞,沒有引用傳遞。普通資料型別直接傳遞值,而對於引用型別來說傳遞值是所引用物件在堆區的記憶體地址。