第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

方法引用似乎并不總是捕獲實例

方法引用似乎并不總是捕獲實例

蝴蝶不菲 2023-01-05 17:25:37
我知道關(guān)于這個主題有很多問題,即使是最近的一個問題,但我仍然無法解決一件事??紤]以下功能接口:@FunctionalInterfaceinterface PersonInterface {    String getName();}而這個實現(xiàn):class Person implements PersonInterface {    private String name;    public Person(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}如果我查看這些線程1和2,我希望輸出以下代碼"Bob"而不是拋出 aNullPointerException因為據(jù)我所知,當(dāng)我創(chuàng)建供應(yīng)商時,它會捕獲Person實例。Person p = new Person("Bob");Supplier<String> f = p::getName;p = null;System.out.println(f.get());它正確輸出"Bob"現(xiàn)在我不明白的是為什么下面的代碼也沒有輸出"Bob"?Person p = new Person("Bob");Supplier<String> f = p::getName;p.setName("Alice");System.out.println(f.get());它實際上輸出"Alice"在我看來,在第一個示例中,lambda 在創(chuàng)建時捕獲了 Person 對象的狀態(tài),并且在調(diào)用它時不會嘗試重新評估它,而在第二種情況下,它似乎沒有捕獲它,但在調(diào)用時重新評估它。編輯 在重新閱讀其他線程和 Eran 的回答后,我用 2 個人指向同一個實例寫了那個:Person p1 = new Person("Bob");Person p2 = p1;Supplier<String> f1 = p1::getName;Supplier<String> f2 = p2::getName;p1 = null;p2.setName("Alice");System.out.println(f1.get());System.out.println(f2.get());現(xiàn)在我可以看到它們都輸出"Alice",即使 p1 為空,因此方法引用捕獲了實例本身,而不是我錯誤假設(shè)的狀態(tài)。
查看完整描述

2 回答

?
桃花長相依

TA貢獻(xiàn)1860條經(jīng)驗 獲得超8個贊

在我看來,在第一個示例中,lambda 在創(chuàng)建時捕獲了 Person 對象的狀態(tài),并且在調(diào)用它時不會嘗試重新評估它,而在第二種情況下,它似乎沒有捕獲它,但在調(diào)用時重新評估它。

首先,它是一個方法引用,而不是 lambda 表達(dá)式。

在這兩種情況下,對Person實例的引用都被方法引用捕獲(這不是“Person 對象的狀態(tài)”)。這意味著如果Person實例的狀態(tài)發(fā)生變化,則執(zhí)行功能接口的方法的結(jié)果可能會發(fā)生變化。

方法引用不會創(chuàng)建Person它捕獲其引用的實例的副本。


查看完整回答
反對 回復(fù) 2023-01-05
?
侃侃無極

TA貢獻(xiàn)2051條經(jīng)驗 獲得超10個贊

這在某種程度上與 lambdas 或方法引用無關(guān),它只是您正在使用的這些構(gòu)造的副作用。


為了更簡單的推理,您可以將其視為:


static class SupplierHolder {

    private final Person p;

    // constructor/getter

}


static class Person {

    private String name;

    // constructor/getter/setter

}

當(dāng)您創(chuàng)建:Supplier<String> f = p::getName;時,您可以將其視為創(chuàng)建一個SupplierHolder以 aPerson作為輸入并具有對其getName.


這就像做:


Person p = new Person("Bob");

SupplierHolder sh = new SupplierHolder(p);

p = null; // this has no effect on the reference that SupplierHolder holds

System.out.println(sh.getPerson().getName()); 

在你的第二個例子中,你有:


Person p = new Person("Bob");

SupplierHolder sh = new SupplierHolder(p); 

p.setName("Alice");

現(xiàn)在p引用和SupplierHolder持有的引用“作用于”同一個實例——它們指向同一個對象。


這在現(xiàn)實中并不完全相同,但我想證明了這一點(diǎn)。


查看完整回答
反對 回復(fù) 2023-01-05
  • 2 回答
  • 0 關(guān)注
  • 170 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號