2 回答

TA貢獻1860條經驗 獲得超8個贊
在我看來,在第一個示例中,lambda 在創建時捕獲了 Person 對象的狀態,并且在調用它時不會嘗試重新評估它,而在第二種情況下,它似乎沒有捕獲它,但在調用時重新評估它。
首先,它是一個方法引用,而不是 lambda 表達式。
在這兩種情況下,對Person
實例的引用都被方法引用捕獲(這不是“Person 對象的狀態”)。這意味著如果Person
實例的狀態發生變化,則執行功能接口的方法的結果可能會發生變化。
方法引用不會創建Person
它捕獲其引用的實例的副本。

TA貢獻2051條經驗 獲得超10個贊
這在某種程度上與 lambdas 或方法引用無關,它只是您正在使用的這些構造的副作用。
為了更簡單的推理,您可以將其視為:
static class SupplierHolder {
private final Person p;
// constructor/getter
}
static class Person {
private String name;
// constructor/getter/setter
}
當您創建:Supplier<String> f = p::getName;時,您可以將其視為創建一個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");
現在p引用和SupplierHolder持有的引用“作用于”同一個實例——它們指向同一個對象。
這在現實中并不完全相同,但我想證明了這一點。
添加回答
舉報