變量的修改結(jié)果無法預(yù)知源于共享的可變數(shù)據(jù)京痢,很難追蹤是哪個實例修改了變量欲主。
如果一個方法只是把計算結(jié)果return芍锚,而不修改內(nèi)部狀態(tài),這個方法就是無副作用的僻弹。
我們允許函數(shù)內(nèi)部執(zhí)行一些非函數(shù)式帶有副作用的操作阿浓,只要這些操作的結(jié)果不會暴露給系統(tǒng)中的其他部分,調(diào)用者不需要知道蹋绽,或者完全不在意這些副作用芭毙,因為這對它完全沒有影響。
我們的準則是卸耘,被稱為“函數(shù)式”的函數(shù)或方法都只能修改本地變量退敦。除此之外,它引用的對象都應(yīng)該是不可修改的對象蚣抗。所有的字段都是final類型侈百,引用類型(即非基本類型)字段都指向不可變對象。
函數(shù)或者方法不應(yīng)該拋出任何異常翰铡,不再像預(yù)期那樣钝域,返回一個恰當(dāng)?shù)慕Y(jié)果值。對于諸如除數(shù)是零這種異常情況锭魔,使用Optional類型例证,要么成功返回值,要么返回對象表示其無法進行指定的操作迷捧。也可以選擇在本地局部使用異常织咧,避免通過接口將結(jié)果暴露給其他方法胀葱,不會過去膨脹代碼。
函數(shù)式編程寫出來的代碼笙蒙,可以在任何時候作為函數(shù)被其他地方復(fù)用抵屿。
遞歸和迭代
像while或者for這樣的迭代構(gòu)造器經(jīng)常隱藏著陷阱,誘使你修改對象手趣。比如while循環(huán)中晌该,循環(huán)的條件需要更新。盡量使用Stream代替迭代绿渣,避免變化帶來的影響朝群。
技巧
高階函數(shù)
能夠接受至少一個函數(shù)作為參數(shù),或者返回的結(jié)果是一個函數(shù)中符。
// 返回一個函數(shù)
Function<Integer, String> getMyFunction() {
return (it) -> "Hello, world: " + it;
}