日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】探究Java方法的参数传递是值传递还是引用传递

發布時間:2025/3/15 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】探究Java方法的参数传递是值传递还是引用传递 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

測試思路

每個更改形參的方法,返回值都是void,不同方法的參數設置不同類型。

注意在方法內測地址的時候在改之前測一下,才能看出傳入參數是不是傳了地址。(注意反正OS的內存地址是虛擬的,JVM中的也是,掰扯不清的,所以就姑且按照JVM中的虛擬地址來考慮吧)

數組參數傳遞

private static void changeArray(int[] array) {Arrays.fill(array, 2); }

數組的值改變了,但地址沒變,是引用傳遞。

基本類型及其包裝類的參數傳遞

private static void changeInt(int data) {data = 3; }private static void changeInteger(Integer data) {data = 3; }

無論是int還是Integer,沒有返回值,所以外面的實參值沒變。

對于基本類型,打印地址也能看出地址改了,是值傳遞。
對于包裝類型,打印地址能看出地址沒改,是引用傳遞。

由于hashCode()被重寫了,所以可以用System.out.println(System.identityHashCode(data));來看虛擬地址(當然不是真的地址啦)。

普通類參數傳遞

private static class Person {int id;String name;int age;Person(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';} }private static void changePerson(Person data) {data = new Person(101, "Bob", 15); }

是引用類型,也是引用傳遞。打印地址測試過,確實在new之前的虛擬地址與傳入實參的虛擬地址一致。(想測地址就把@Override的toString()注釋掉,再打印對象啊)

只改屬性

private static void changePersonAttributes(Person data) {data.id = 101;data.name = "Bob";data.age = 15; }

改了屬性,打印結果改了,但是實際地址沒改,說明是引用傳遞。

完整代碼

部分打印地址的測試內容就刪掉不附上了,感興趣可以自測。

import java.util.Arrays;public class ReferenceTest {private static void changeArray(int[] array) {Arrays.fill(array, 2);}private static void changeInt(int data) {data = 144;}private static void changeInteger(Integer data) {data = 155;}private static class Person {int id;String name;int age;Person(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';}}private static void changePerson(Person data) {data = new Person(101, "Bob", 15);}private static void changePersonAttributes(Person data) {data.id = 101;data.name = "Bob";data.age = 15;}public static void main(String[] args) {int[] array = new int[5];System.out.println(Arrays.toString(array));changeArray(array);System.out.println(Arrays.toString(array));Integer a = 133;changeInteger(a);System.out.println(a);changeInt(a);System.out.println(a);Person p = new Person(100, "Sam", 10);System.out.println(p);changePerson(p);System.out.println(p);changePersonAttributes(p);System.out.println(p);} }

測試結果

[0, 0, 0, 0, 0] [2, 2, 2, 2, 2] 133 133 Person{id=100, name='Sam', age=10} Person{id=100, name='Sam', age=10} Person{id=101, name='Bob', age=15}

總結反思

其實自己也一直沒搞明白Java的參數傳遞到底是值傳遞還是引用傳遞,網上說法眾說紛紜,于是下定決心自己認真測一下。

按照JVM的虛擬地址來做測試,在整數測試的時候還考慮了整數緩存池,選了127以上的數。

個人認為,其實不能單純利用返回值為void的函數運行后查看原值來判斷是值傳遞還是引用傳遞。我選擇在傳完參數后的函數內測地址,地址一樣就是引用傳遞,不一樣就是值傳遞。
hashCode()一般包含了地址,但Integer的hashCode()則只是原值,得使用System.identityHashCode(data)來測。

emmm,接下來,講講結論orz

總結

  • 基本類型是值傳遞
  • 引用類型是引用傳遞,返回值為void的話未必能在外面看到改變。
    • 引用類型對象重新被new了以后,看不到改變;但改變屬性能看到改變。
    • 數組也是引用類型,數組元素值的改變能在void方法外面測出來。

其實研究這個問題Real迷惑,如有不足還請指正!


Update on 2020.3.7
強調String這個問題,如果你簡單地測試得到地址沒變,這是不對的,涉及到String常量池等等……
因為我還不太會,所以回頭再來補充orz

看來這篇文章可能有些我思慮不周(尚未涉獵)的地方啊,果然水深莫涉啊orz

總結

以上是生活随笔為你收集整理的【Java】探究Java方法的参数传递是值传递还是引用传递的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。