差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

Both sides previous revision 前次修改
下次修改
前次修改
java:effective_java:methods:return_optionals_judiciously [2021/07/05 08:45]
tony [Rule#3: Prefer alternatives APIs over Optional.isPresent() and Optional.get().]
java:effective_java:methods:return_optionals_judiciously [2023/06/25 09:48] (目前版本)
行 61: 行 61:
 最後是最有爭議的,是否要將Optional使用於field。反對者主要有以下論述:​ 最後是最有爭議的,是否要將Optional使用於field。反對者主要有以下論述:​
   * Optional不支援序列化,這個是主因。(列為anti-pattern的主因)   * Optional不支援序列化,這個是主因。(列為anti-pattern的主因)
-  * 多消耗4x記憶體空間。(演講中有提及)+  * 多消耗4倍記憶體空間。(演講中有提及)
   * Optional是一個box,包覆另外一個value物件,這會增加額外的GC開銷。(演講中有提及)   * Optional是一個box,包覆另外一個value物件,這會增加額外的GC開銷。(演講中有提及)
-針對以上三點,序列化問題可以透過Guava Optional或Vivr Optional去解決,但也要搭配[[java:​jackson:​deepclone|Jackson Module]]或Gson的TypeAdapter做對應的處理;多消耗4x記憶體空間在現在時代已經不是嚴重的事情(Stuart Marks的演講有提及);在Java8的情況下,第三點就無法避免了。\\+針對以上三點,序列化問題可以透過Guava Optional或Vivr Optional去解決,但也要搭配[[java:​jackson:​deepclone|Jackson Module]]或Gson的TypeAdapter做對應的處理;多消耗4倍記憶體空間在現在時代已經不是嚴重的事情(Stuart Marks的演講有提及);在Java8的情況下,第三點就無法避免了。\\
 目前已知的是,JDK的[[https://​openjdk.java.net/​projects/​valhalla/​|Valhalla]]專案希望能夠將Optional變成Value Type去避免這個問題,也因為有這個計畫,導致目前無法讓Optional去實作Serializable(會產生向下相容問題)。JodaTime作者認為如果這天來臨,內建的Optional應可以用於任何地方:​\\ 目前已知的是,JDK的[[https://​openjdk.java.net/​projects/​valhalla/​|Valhalla]]專案希望能夠將Optional變成Value Type去避免這個問題,也因為有這個計畫,導致目前無法讓Optional去實作Serializable(會產生向下相容問題)。JodaTime作者認為如果這天來臨,內建的Optional應可以用於任何地方:​\\
 {{:​java:​effective_java:​methods:​effectivejava_item55_optional_with_serializable.png|}}\\ {{:​java:​effective_java:​methods:​effectivejava_item55_optional_with_serializable.png|}}\\
行 78: 行 78:
 \\ \\
 支持者的論點,主要有兩點:​ 支持者的論點,主要有兩點:​
-  * 宣告於欄位代表著非必要欄位,語意表達比使用null加註解清楚,更何況大家都不愛寫註解。[[https://​nipafx.dev/​stephen-colebourne-java-optional-strict-approach/​|link]] +  * 宣告於欄位代表著非必要欄位,語意表達比使用null加註解清楚,更何況大家都不愛寫註解。此外,這個Optional支持者反對null,不偏好JodaTime作者的方法。[[https://​nipafx.dev/​stephen-colebourne-java-optional-strict-approach/​|link]] 
-  * Effective Java Item 55有提及,適用於物件有許多非必要欄位的情況,像是部分更新的UseCaseInput model。如果按照Stuart Marks的建議使用Null Object Pattern,那將會因此建立許多Sub Classes,非常不方便。+  * Effective Java Item 55有提及,適用於物件有許多非必要欄位的情況,像是部分更新的UseCaseInput model。如果按照Stuart Marks的建議使用Null Object Pattern,那將會因此建立許多Sub Classes,非常不方便。
   * 在使用Lombok的情況下,有人會想將Optional宣告為field;但被Lombok開發人員打槍,因為他愛null。[[https://​stackoverflow.com/​questions/​31670785/​optional-in-lombok|link]]   * 在使用Lombok的情況下,有人會想將Optional宣告為field;但被Lombok開發人員打槍,因為他愛null。[[https://​stackoverflow.com/​questions/​31670785/​optional-in-lombok|link]]
-支持者與反對者比較寫法如下,我認為trade-off就在對於效能、寫法、序列化與框架的使用上了,單元測試成本幾乎是一樣的:​+支持者與反對者比較寫法如下,我認為trade-off就在對於效能、語意、序列化與框架的使用上了,單元測試成本幾乎是一樣的:​
 <code java> <code java>
 private String mail; // optional private String mail; // optional
行 103: 行 103:
 } }
 </​code>​ </​code>​
 +在Java 8的情況下,我提供以下主要的trade-off比較給大家參考:​
 +  * 允許Optional於欄位讓語意清楚:​ 效能較差、維護成本較高(有序列化需求要特別套其它library)。
 +  * 允許null於欄位並僅在回傳值使用Optional:​ 僅有語意問題,null控制好就無大礙。
 ==== Rule#7: Avoid using identity-sensitive operations on Optionals. For example don’t use reference equality == with Optionals. ==== ==== Rule#7: Avoid using identity-sensitive operations on Optionals. For example don’t use reference equality == with Optionals. ====
 這個Rule是告訴大家不要把Optional的物件使用==去操作,要用equals;除了這個以外,也不要把它拿來synchronized。主要原因是Optional本質上是一個包裝物件的box,未來有很大的機會變成Value Type,參考此[[https://​openjdk.java.net/​projects/​valhalla/​|link]]。 這個Rule是告訴大家不要把Optional的物件使用==去操作,要用equals;除了這個以外,也不要把它拿來synchronized。主要原因是Optional本質上是一個包裝物件的box,未來有很大的機會變成Value Type,參考此[[https://​openjdk.java.net/​projects/​valhalla/​|link]]。