不少書中都提到了在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