欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java?引用傳遞的三種類型小結

 更新時間:2022年02月15日 14:32:12   作者:源君  
這篇文章主要介紹了java?引用傳遞的三種類型,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

java引用傳遞的三種類型

我這里使用了mldn視頻里的例子,只用于學習交流。

第一種

結果:調用前:50

調用后:1000

分析:

理解:好理解

第二種傳遞方式

先看例子

運行結果:

分析圖片:

第三種傳遞方式

結果:

分析:

對于三種引用傳遞的理解

第一種和第三種都好理解:

其實就是c語言那樣傳遞的是地址,當然能夠修改屬性值,對于第二種其實就是因為String類比較特殊,在第二個例子中fun()函數str2="mldn"其實mldn是個匿名對象?。。∵@個等式其實就是將str2的引用的地址值改變了,也即使str1的引用地址指向了mldn這個在堆內存的這個對象。

java引用傳值問題

一圖勝萬言(配上一張啟艦大神的圖,一個自定義控件寫的很吊的大神):

這幾天一直在寫一個項目,果然只搞理論是不行的,距離上一次寫項目已經快有半年了,今天無論是效率還是熟練度都大不如前

好了言歸正傳,今天要說的這個問題其實很簡單——在java中的參數傳遞問題。(其實我承認,這個地方我只是知道對象傳引用、普通類型傳值,典型的理論派-。+),但是這個問題可大可小,我覺得還是要把這些縷得清清楚楚才好。

問題起源,一個蠢到家的是失敗案例

其實今天寫這篇文章完全是咋呼-。+,恰好是因為自己在做RecyclerView的萬能適配器的時候出現的問題,先給大家引入一下當時的場景:

    @Override
    public void resultCallbackFromFragment(List<Contact> list) {
        Toast.makeText(this, "修改成功!", Toast.LENGTH_SHORT).show();
        ......
        contactList = list;
        adapter.notifyDataSetChanged();
        ......
    }

只留下了我們設計的代碼,其他部分的代碼全部打……了。接下來我用極其簡單的組織語言介紹一下場景:

打開一個具有復選框的界面,退出時返回選中的數據,方法為一個回調方法,方法的效果是更新列表數據(contactList為我們傳入RecyclerView的源數據)。

理論上說先給contactList更新為獲取到的最新的值,然后調用notifyDataSetChanged方法,列表就刷新了,看上去一切都是那么的圓滿。然后我們看一下效果:

不要吐槽這個App背景,因為是給我的小仙女做的-。+!

在上面的效果中,我們看到,在選中了兩個聯系人,點擊確定之后,按道理說應該是顯示成兩個人,怎么還是剛才的數據呢?

當時也是知道引用類型的傳遞傳遞的是引用,回憶了一下自己當時的思路:引用傳遞給了另一個引用,這一個引用的內容改變了,所有的都改變了。。。。 (可能有的朋友看到我這句話覺得很好笑:哇博主你好菜啊,這么基礎的問題都被繞住了,好吧我得承認java基礎是有些差。。)

就是這么簡單的一句話讓我饒了好幾個大彎,當時自己已經被繞進去了,覺得這個數據就是被改變了啊,然后就開始從其他地方找錯誤,過了好久才開始反思:是不是數據傳遞的過程出現了點問題-。+

然后自己就開始查找參數傳遞相關問題,好了,現在開始,我們先跳出上面這個案例中,我不希望大家被上面花里胡哨的東西影響,因為我們今天講的問題只有一個:java的引用傳值。

兩類參數傳遞

參數傳遞主要分為兩種:一種是參數是基本類型,一種是參數為引用類型。

基本數據類型

這個相信大家都沒什么問題,基本類型作為參數傳遞的時候是在一個方法棧中開辟了一塊新內存,拷貝了原來的數據值,所以無論我們如何修改,原來的數據值不會受到任何影響。

舉個簡單的栗子:

public class Practice2 { 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a = 5;
		System.out.println(a);
		change(a);
		System.out.println(a);
	} 
	public static void change(int b) {
		b = 500;
	}
}

結果如下:

5
5

沒有任何變化,對吧。

引用數據類型

首先我們要知道引用的數據存儲在棧內存中,而引用指向的對象存儲在堆內存中。

當引用作為方法參數傳遞給方法的時候,是將引用的值拷貝一份給另一個引用,但引用指向的都是同一個堆內存,所以進行的修改操作同樣有效。

實例代碼:

public class Practice { 
	static A a = new A(10);
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Practice practice = new Practice();
		System.out.println(practice.a.intData);
		change(practice.a);
		System.out.println(practice.a.intData);
	} 
	public static void change(A aa) {
		aa.intData = 500;
		System.out.println(aa.intData);
	}
} 
class A{
	int intData; 
	public A(int intData) {
		this.intData = intData;
	}	
}

10
500

這么說起來沒什么難度,對吧。

引用傳遞

其實上面所說的引用形參傳遞,本質上就是引用的傳遞,我們將引用傳遞給了另一個引用,那么這兩個引用都有了相同的值——既指向了相同的對象。

A a1 = new A(10);
A a2 = a1;
System.out.println("a1的intData: " + a1.intData + "   a2的intData:  " + a2.intData );
a2.intData = 500;
System.out.println("a1的intData: " + a1.intData + "   a2的intData:  " + a2.intData );

結果如下:

a1的intData: 10   a2的intData:  10
a1的intData: 500   a2的intData:  500

注意):引用類型中,形參能夠改變實參的值,或者一個引用能夠改變另一個引用的值,僅僅是因為他們棧內存中存儲的值相同,但這個值是隨時可以修改的。

這個也就是本人之前一直被困住的地方,其實只要引用存儲的值改變了,這兩個引用就毫無關系了。請見下面的例子:

A a1 = new A();
A a2 = a1;
System.out.println(a1);
System.out.println(a2);
a2 = new A();
System.out.println(a1);
System.out.println(a2);

結果如下:

A@33909752
A@33909752
A@33909752
A@55f96302

在a2指向新的對象后,a1和a2就已經沒有任何關系了,因為他們兩個引用存儲的值已經完全不一樣了。

相信這張圖已經說的很明白了吧。

反過來再解決這個案例

現在有了上面的理論知識,我們在反過頭來看一開始的這個問題。

    @Override
    public void resultCallbackFromFragment(List<Contact> list) {
        Toast.makeText(this, "修改成功!", Toast.LENGTH_SHORT).show();
        ......
        contactList = list;
        adapter.notifyDataSetChanged();
        ......
    }

在我們獲取到了新的list之后,是給contactList賦值了一個新的引用,此時他指向的為一個新的堆內存空間。但是適配器中的list還是指向之前的引用,因為我們只是改變了contactList引用的值,然后執(zhí)行notifyDataSetChanged方法,可是適配器中l(wèi)ist數據還是原來contactList指向的數據。

因此解決的辦法是:直接改變適配器中的list引用,然后調用notifyDataSetChanged方法:

    public void notifyData(List<T> mList){
        this.mList = mList;
        notifyDataSetChanged();
    }

直接在適配器中寫一個修改數據的方法,然后在外面調用就好啦:

    @Override
    public void resultCallbackFromFragment(List<Contact> list) {
        Toast.makeText(this, "修改成功!", Toast.LENGTH_SHORT).show();
        ......
        contactList = list;
        adapter.notifyData(contactList);
        ......
    }

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • JAVA正則表達式匹配多個空格的解決方案

    JAVA正則表達式匹配多個空格的解決方案

    這篇文章主要介紹了JAVA正則表達式匹配多個空格的解決方案,文中提到了()和[]本質的區(qū)別,本文給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-11-11
  • SpringBoot war包部署到Tomcat服務器

    SpringBoot war包部署到Tomcat服務器

    這篇文章主要介紹了SpringBoot war包部署到Tomcat服務器,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • 解析Java的可變長參數列表及其使用時的注意點

    解析Java的可變長參數列表及其使用時的注意點

    這篇文章主要介紹了解析Java的可變參數列表及其使用時的注意點,注意可變參數必須位于最后一項,需要的朋友可以參考下
    2016-03-03
  • 用Spring Native將SpringBoot程序轉換為GraalVM

    用Spring Native將SpringBoot程序轉換為GraalVM

    這篇文章主要介紹了用Spring Native將SpringBoot程序轉換為GraalVM的方法,幫助大家更好的理解和學習使用SpringBoot,感興趣的朋友可以了解下
    2021-04-04
  • MyBatis使用Map與模糊查詢的方法示例

    MyBatis使用Map與模糊查詢的方法示例

    這篇文章主要給大家介紹了關于MyBatis使用Map與模糊查詢的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • mybatis一對多兩種mapper寫法實例

    mybatis一對多兩種mapper寫法實例

    這篇文章主要介紹了mybatis一對多兩種mapper寫法實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 全面解析SpringBoot自動配置的實現原理

    全面解析SpringBoot自動配置的實現原理

    這篇文章主要介紹了全面解析SpringBoot自動配置的實現原理的相關資料,需要的朋友可以參考下
    2017-05-05
  • java之函數式接口解讀

    java之函數式接口解讀

    這篇文章主要介紹了java之函數式接口,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring?Boot?打包如何將依賴全部打進去

    Spring?Boot?打包如何將依賴全部打進去

    這篇文章主要介紹了Spring?Boot?打包如何將依賴全部打進去,在pom.xml中引入插件,需要在項目的pom.xml文件中,添加?Maven?插件??spring-boot-maven-plugin,本文結合實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • 基于SpringBoot2.0版本與老版本的區(qū)別

    基于SpringBoot2.0版本與老版本的區(qū)別

    這篇文章主要介紹了SpringBoot2.0版本與老版本的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10

最新評論