Java中值傳遞和引用傳遞的概念

不少書中都提到了在Java中只存在值傳遞,可是今天在一個NanoHTTPD的源碼中看到這樣一段:java

 

1 if (qmi >= 0) {
2   decodeParms(uri.substring(qmi + 1), parms);
3   uri = decodePercent(uri.substring(0, qmi));
4 }
 1 /**
 2          * Decodes parameters in percent-encoded URI-format ( e.g.
 3          * "name=Jack%20Daniels&pass=Single%20Malt" ) and adds them to given
 4          * Map. NOTE: this doesn't support multiple identical keys due to the
 5          * simplicity of Map.
 6          */
 7         private void decodeParms(String parms, Map<String, String> p) {
 8             if (parms == null) {
 9                 p.put(QUERY_STRING_PARAMETER, "");
10                 return;
11             }
12 
13             p.put(QUERY_STRING_PARAMETER, parms);
14             StringTokenizer st = new StringTokenizer(parms, "&");
15             while (st.hasMoreTokens()) {
16                 String e = st.nextToken();
17                 int sep = e.indexOf('=');
18                 if (sep >= 0) {
19                     p.put(decodePercent(e.substring(0, sep)).trim(),
20                             decodePercent(e.substring(sep + 1)));
21                 } else {
22                     p.put(decodePercent(e).trim(), "");
23                 }
24             }
25         }

 

上面代碼是在調用decodeParms方法的時候傳入一個Map對象,該方法返回是void型,所以傳入的參數只能在方法內部修改,而不能返回,可是這段代碼很明顯是影響到對了方法外部的這個對象。這跟java中只有值傳遞的說法不一致,難道java中存在引用傳遞?ide

 

後來查閱文檔後發現,java中確實是只存在值傳遞。java中對象和基本類型的傳遞參數傳遞方式大不同,對於基本類型,java只是拷貝一個它自己的副本,而對象傳遞則是傳遞指向該對象的指針的值。this

然而傳遞對象的指針的值並不表明是引用傳遞,看下面一段代碼:spa

 1 public class TestPassDemo {
 2     
 3     @Test
 4     public void  test() {
 5         TestPassDemo test = new TestPassDemo();
 6         Map<String, String> map1 = new HashMap<String, String>();
 7         map1.put("username", "David");
 8         Map<String, String> map2 = new HashMap<String, String>();
 9         map2.put("username", "Nick");
10         String user = "David";
11         int i = 1;
12         changeValue(map1,map2, user,i);
13         
14         //若是打印的是:{username=admin}則說明java的對象傳遞的是地址,若是是:{username=David}則傳遞的是值
15         System.out.println(map1);//{username=admin}
16         
17         System.out.println(map2);//{username=Nick}
18         //若是打印的是:admin則說明java的String對象傳遞的是地址,若是是:David則傳遞的是值
19         System.out.println(user);//David
20         System.out.println(i+"");//1
21     }
22     
23     public void changeValue(Map<String, String> map1,Map<String, String> map2, String str,int i){
24         map2 = map1;
25         map1.put("username", "Jack");
26         map2.put("username", "admin");
27         str = "admin";
28         i = 10;
29     }
30 
31 }

最後輸出的結果是這樣的:指針

{username=admin}
{username=Nick}
David
1

 

這說明了java中對象的傳遞只是一個指向該對象的指針的值,實際上也能夠理解爲一種值傳遞。code

這就解釋了上面說的java中只存在值傳遞方法內部爲什麼卻能改變外部的變量。orm

所謂java中的對象,實際上就是C語言中的指針的概念,本質上就是:在堆內存中開闢一塊空間,而後使用一個指針來引用它,舉一個例子來講的話:對象

 

一個Person對象是java中的一個對象,Person有name和age屬性,這時須要用一個指針來引用這個Person對象,Person對象又包含了對name對象和age對象的引用,所謂java的對象實際上也是利用C語言的這種指針的概念來實現的。blog

相關文章
相關標籤/搜索