關於JAVA的傳值與引用的理解
接上上次的問題 聽說可以用引用來解決那個問題。 如果沒連結的話。請看基礎篇---》JAVA反射的那篇後續寫了這個。引用與反射
通過這個我們發現 或者你自己去測試寫一個類Int 和String 都是final 類感覺很類似。而且內部也沒有什麼方法可以去修改值。
唯獨Stringbuffer 可以修改。這個應該和他們的記憶體儲存的方式有影響。
詳細的內容自己可以百度去找下。方法的內部變數。在使用後自動被系統收回。而不改變方法外的變數值。
這就是引用不到方法外的變數。雖然傳值也傳了。具體的話。有大牛來反駁我的解釋 我虛心接收學習。
開始理解概念上的東西了這裡我就不寫了複製下,
1. 簡單型別是按值傳遞的
Java方法的引數是簡單型別的時候,是按值傳遞的 (pass by value)。這一點我們可以通過一個簡單的例子來說明:
[java] view plain copy print?- /*例 1 */
- /**
- * @(#) Test.java
- * @author fancy
- */
- publicclass Test {
- publicstaticvoid test(boolean test) {
- test = ! test;
-
System.out.println("In test(boolean): test = "
- }
- publicstaticvoid main(String[] args) {
- boolean test = true;
- System.out.println("Beforetest(boolean) : test = " + test);
- test(test);
- System.out.println("Aftertest(boolean) : test = " + test);
- }
- }
執行結果:
[plain]- Beforetest(boolean) : test = true
- In test(boolean) : test = false
- After test(boolean) : test = true
不難看出,雖然在 test(boolean) 方法中改變了傳進來的引數的值,但對這個引數源變數本身並沒有影響,即對 main(String[]) 方法裡的 test 變數沒有影響。那說明,引數型別是簡單型別的時候,是按值傳遞的。以引數形式傳遞簡單型別的變數時,實際上是將引數的值作了一個拷貝傳進方法函式的,那麼在方法函式裡再怎麼改變其值,其結果都是隻改變了拷貝的值,而不是源值。
2. 什麼是引用
Java是傳值還是傳引用,問題主要出在物件的傳遞上,因為 Java 中簡單型別沒有引用。既然爭論中提到了引用這個東西,為了搞清楚這個問題,我們必須要知道引用是什麼。
簡單的說,引用其實就像是一個物件的名字或者別名 (alias),一個物件在記憶體中會請求一塊空間來儲存資料,根據物件的大小,它可能需要佔用的空間大小也不等。訪問物件的時候,我們不會直接是訪問物件在記憶體中的資料,而是通過引用去訪問。引用也是一種資料型別,我們可以把它想象為類似 C 語言中指標的東西,它指示了物件在記憶體中的地址——只不過我們不能夠觀察到這個地址究竟是什麼。
如果我們定義了不止一個引用指向同一個物件,那麼這些引用是不相同的,因為引用也是一種資料型別,需要一定的記憶體空間來儲存。但是它們的值是相同的,都指示同一個物件在記憶體的中位置。比如
[java] view plain copy print?- Stringa = "Hello";
- String b = a;
這裡,a和 b 是不同的兩個引用,我們使用了兩個定義語句來定義它們。但它們的值是一樣的,都指向同一個物件"Hello"。也許你還覺得不夠直觀,因為 String 物件的值本身是不可更改的 (像 b = "World"; b = a; 這種情況不是改變了 "World" 這一物件的值,而是改變了它的引用b 的值使之指向了另一個 String 物件 a)。那麼我們用 StringBuffer 來舉一個例子:
[java] view plain copy print?- /*例 2 */
- /**
- * @(#) Test.java
- * @author fancy
- */
- publicclass Test {
- publicstaticvoid main(String[] args) {
- StringBuffer a = newStringBuffer("Hello");
- StringBuffer b = a;
- b.append(", World");
- System.out.println("a is "+ a);
- }
- }
執行結果:
[java] view plain copy print?- ais Hello, World
這個例子中 a 和 b 都是引用,當改變了 b 指示的物件的值的時候,從輸出結果來看,a 所指示的物件的值也改變了。所以,a 和b 都指向同一個物件即包含 "Hello" 的一個 StringBuffer 物件。
這裡我描述了兩個要點:
1. 引用是一種資料型別,儲存了物件在記憶體中的地址,這種型別即不是我們平時所說的簡單資料型別也不是類例項(物件);
2. 不同的引用可能指向同一個物件,換句話說,一個物件可以有多個引用,即該類型別的變數。
3. 物件是如何傳遞的呢
關於物件的傳遞,有兩種說法,即“它是按值傳遞的”和“它是按引用傳遞的”。這兩種說法各有各的道理,但是它們都沒有從本質上去分析,即致於產生了爭論。
既然現在我們已經知道了引用是什麼東西,那麼現在不妨來分析一下物件作是引數是如何傳遞的。還是先以一個程式為例:
[java] view plain copy print?- /*例 3 */
- /**
- * @(#) Test.java
- * @author fancy
- */
- publicclass Test {
- publicstaticvoid test(StringBuffer str) {
- str.append(", World!");
- }
- publicstaticvoid main(String[] args) {
- StringBuffer string = newStringBuffer("Hello");
- test(string);
- System.out.println(string);
- }
- }
執行結果:
[java] view plain copy print?- Hello,World!
test(string)呼叫了 test(StringBuffer) 方法,並將 string 作為引數傳遞了進去。這裡 string 是一個引用,這一點是勿庸置疑的。前面提到,引用是一種資料型別,而且不是物件,所以它不可能按引用傳遞,所以它是按值傳遞的,它麼它的值究竟是什麼呢?是物件的地址。
由此可見,物件作為引數的時候是按值傳遞的,對嗎?錯!為什麼錯,讓我們看另一個例子:
[java] view plain copy print?- /*例 4 */
- /**
- * @(#) Test.java
- * @author fancy
- */
- publicclass Test {
- publicstaticvoid test(String str) {
- str = "World";
- }
- publicstaticvoid main(String[] args) {
- String string = "Hello";
- test(string);
- System.out.println(string);
- }
- }
執行結果:
-
相關推薦
關於JAVA的傳值與引用的理解
接上上次的問題 聽說可以用引用來解決那個問題。 如果沒連結的話。請看基礎篇---》JAVA反射的那篇後續寫了這個。引用與反射 通過這個我們發現 或者你自己去測試寫一個類Int 和String 都是final 類感覺很類似。而且內部也沒有什麼方法可以去修
微信小程式資料傳值與引用data變數
1、在微信小程式中通過點選方法進行變數賦值,可以將數值定義在e.currentTarget.dataset裡 通過定義data-x,將index值進行傳遞 <block wx:for="{{imgUrls}}" wx:key="{{index}}"&g
Java中傳值與傳遞引用的區分
基本型別傳的是值,例如:int,float,double,char,不包括 java.lang.String 物件例項,介面例項傳的是引用,包括java.lang.String。但是我們在通過一個函式傳遞String引數時,為何出來的結果沒有發生改變?如下所示: void
java中的經典問題:傳值與傳引用
引數傳遞的祕密 知道方法引數如何傳遞嗎?記得剛開始學程式設計那會兒,老師教導,所謂引數,有形式引數和實際引數之分,引數列表中寫的那些東西都叫形式引數,在實際呼叫的時候,它們會被實際引數所替代。編譯程式不可能知道每次呼叫的實際引數都是什麼,於是寫編譯器的高手就出個辦法,讓實
Java函式中傳值與傳引用的區別
1、對於基本資料型別,傳遞到函式中的是源變數的值 看下面例子: public class Value_Index { public static void main(String[] args){
深入理解PHP中賦值與引用
str ring int 之前 不同 重新 small nts 計數 【原文】 先看下面的問題: 1 2 3 4 5 6 7 8 <?php $a = 10;//將常量值賦給變量,會為a分配內存空間 $b = $a;//變量賦值給變量,是不是
Java學習筆記之物件傳值和引用總結
<strong><span style="font-size:18px;"> public class Test { public static void main(String[] args) { // TODO Auto-generated method s
java傳值傳引用
基礎型別和非集合類的物件都是傳值 集合傳的是引用 class p{ int age; } void changegae(p a){ a.age=2; } int s=1; String x="x"; void changenum(int a){ a=
php中傳值與傳引用的有什麼區別
php傳值:在函式範圍內,改變變數值得大小,都不不會影響到函式外邊的變數值。 PHP按引用:在函式範圍內,對值的任何改變,在函式外部也有所體現,因為傳引用傳的是記憶體地址。 <?php //傳值 $a = 1; $b = 2; $b = $a; $a = 3; echo $b.
java中傳值與傳地址
相信學習過c的朋友們,對於傳值與傳地址比較熟悉,而在java中這樣的術語用的比較少,那麼到底存不存在傳值與傳地址呢? 答案肯定是:存在的!! 做下列總結: 說明:Student student=new Student();中student就可以看作是c裡面的指標
[UE4]傳值與傳引用
分享 mage 傳引用 nbsp 參數 就會 com 對象 image 值傳遞是圓形圖標 設置引用需要使用Set by ref函數 對象在藍圖中都是以引用傳遞 對象,不需要額外設置參數類型是傳值還是傳引用。 結構體在藍圖中默認是按值傳遞
Java 傳值和傳引用的區別
首先對傳值和傳引用要有個基本的概念 傳值:傳遞的是值的副本。方法中對副本的修改,不會影響到呼叫方。 傳引用:傳遞的是引用的副本,共用一個記憶體,會影響到呼叫方。此時,形參和實參指向同一個記憶體地址。對
java傳值還是傳引用
最近一直在看primer c++,函式一章對c++函式之間傳遞引數有詳細的講解,傳值、傳指標和傳引用的應用與區別都講得很清楚,以前一直用java,由於java沒有指標,當時也沒有引用這個概念,所以沒有對java引數的傳遞有過多的思考,現在搞清楚了c++傳遞引數的機制,自然就會
java傳值和傳引用的問題,String型別不會改變!
java傳值和傳引用的問題,我們都知道,類,陣列,介面和String等等引用資料型別都是傳引用,在方法中修改了引用型別的變數會改變原變數,而像基本資料型別都是傳值,所以不會改變,但是String型別也是
JAVA中物件的賦值與引用
前言 最近在學習紅黑樹,當我嘗試不使用遞迴來實現時,發現自己的大腦陷入了混亂。 究其原因,是對JAVA中的基本型別和引用型別有所誤解。 特地重新搜尋+實踐一番,漲個姿勢。 一番折騰 先找個物件過年 class Node {
java中函數傳值與引用問題
輸出 set 驗證 臨時對象 輸出結果 引用 chan sta 賦值運算 從C++轉java,在使用函數傳對象時,碰到一點問題,今天特意驗證了一下: public class App { public static void doubleTest(double
Python的函式傳值與傳引用簡解
Python到底值傳值還是傳引用? 先看兩段程式碼 程式碼1: 1 2 3 4 5 6 7 >>> a=3 >>> def f(b): ... b=1 ... >>> f
【iOS】代理傳值與塊代碼傳值
ring 方法 nslog 設置代理 轉載 adf delegate alloc 代理傳值 主線程與子線程常常須要進行數據的傳遞。不同的類之間,不同的控制器之間都須要。 並且常常須要監聽一個動作的完畢。而後才去做對應事件。(代理是一對一的關系)。 一、代理傳值 代理
傳值與傳址
分享 span logs .cn 基本類型 傳值 str image mage 基本類型傳值 引用類型傳址 傳值與傳址
JSON傳值與PHP接收的幾種情況
利用Chrome的後臺網路,分析了通過JQuery的$.ajax()把 json 資料 post 給 PHP時的幾種情況: 無法在PHP中通過$_POST 以及 $_REQUEST 獲取json資料,即 $json = $_POST['json'];