<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我這裡使用了mldn視訊裡的例子,只用於學習交流。
結果:呼叫前:50
呼叫後:1000
分析:
理解:好理解
先看例子
執行結果:
分析圖片:
結果:
分析:
第一種和第三種都好理解:
其實就是c語言那樣傳遞的是地址,當然能夠修改屬性值,對於第二種其實就是因為String類比較特殊,在第二個例子中fun()函數str2="mldn"其實mldn是個匿名物件!!!這個等式其實就是將str2的參照的地址值改變了,也即使str1的參照地址指向了mldn這個在堆記憶體的這個物件。
一圖勝萬言(配上一張啟艦大神的圖,一個自定義控制元件寫的很吊的大神):
這幾天一直在寫一個專案,果然只搞理論是不行的,距離上一次寫專案已經快有半年了,今天無論是效率還是熟練度都大不如前
好了言歸正傳,今天要說的這個問題其實很簡單——在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參照的值,然後執行notifyDataSetChanged方法,可是介面卡中list資料還是原來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); ...... }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45