在我關于JCG的第一篇文章中,我想向您展示如何利用Java語言的強大功能輕松地提高代碼的可讀性,即使是非常基本的事情。
讓我們從一個具體的例子開始:
String color = "green";
...
if ( color!=null && color.equals("red") ) {System.out.println("Sorry, red is forbidden !");
}
您可能從Java(或面向對象編程)老師那里學到的第一課是在對象上調用方法之前測試對象的無效性的重要性。 空指針異常(NPE)確實是面向對象語言的代碼中最常見(最令人討厭)的錯誤。
在上面的示例中,可以安全地將'color'字符串對象與常量進行比較之前確保其不為null。 我個人一直認為這是程序員的不必要負擔,尤其是對于Java等現代OO語言而言。 解決方法是,存在一個(確實很愚蠢的)技巧來重寫條件而不必測試無效性。 請記住, equals()方法是對稱的(如果a = b則b = a)。
if ( "red".equals(color) ) {System.out.println("Sorry, red is forbidden !");
}
乍一看,在閱讀時可能會有些反常 ,但是消除污染代碼當然也不是一文不值。
讓我們繼續我們的示例,并假設我們現在想將我們的顏色與多個值進行比較。 Java初學者通常會編寫如下內容:
if ( "red".equals(color) ||"yellow".equals(color) ||"blue".equals(color) ) {System.out.println("This is a primary color");
}
我有時會遇到經驗豐富的Java程序員,他們用以下代碼縮短了很長的if語句:
if ( "red|yellow|blue".indexOf(color)>=0 ) {System.out.println("This is a primary color");
}
聰明嗎? 實際上沒有那么多。 與子字符串一起玩可能是一個危險的游戲。 例如,以下代碼可能不會給出預期的結果,特別是如果您是男人:
String type = "man";
...
if ( "woman|child".indexOf(type)>=0 ) {System.out.println("Women and children first !");
}
如果您希望在美觀和可讀性之間找到良好的平衡,則最好選擇以下替代方法之一。
import java.util.HashSet;
import java.util.Set;public static final Set<string> PRIMARY_COLORS;
static {PRIMARY_COLORS = new HashSet<string>();PRIMARY_COLORS.add("red");PRIMARY_COLORS.add("yellow");PRIMARY_COLORS.add("blue");
}
...
if ( PRIMARY_COLORS.contains(color) ) {System.out.println("This is a primary color");
}
很少有人知道這一點(我承認語法有點奇怪),但是在初始化“原色集 ”時仍然有一種減少代碼冗長的方法:
public static final Set<string> PRIMARY_COLORS = new HashSet<string>() {{ add("red"); add("yellow"); add("blue");
}};
如果對代碼的簡潔性變得癡迷,那么Java Collections Framework也可以解決:
import java.util.Arrays;
import java.util.Collection;public static final Collection<string> PRIMARY_COLORS = Arrays.asList("red", "yellow", "blue");
...
if ( PRIMARY_COLORS.contains(color) ) {System.out.println("This is a primary color");
}
final關鍵字可防止將PRIMARY_COLORS變量重新分配給另一個值集合-當將變量定義為public時,這一點尤其重要。 如果安全是主要問題,則還應將原始集合包裝為不可修改的集合。 這將保證只讀訪問。
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;public static final Collection PRIMARY_COLORS =Collections.unmodifiableCollection( Arrays.asList("red", "yellow", "blue") );
必須注意,盡管更易讀,但使用值的集合(尤其是大型集合)通常會比(而不是像)經典的惰性 OR(即使用'||'而不是' |'),因為存在短路 評估 。 我傾向于認為如今這種考慮是徒勞的。
經過16年的抱怨,Java 7終于有了! –在switch-case語句中引入了對String的支持。 這使我們可以編寫如下代碼:
boolean primary;
switch(color) {case "red":primary=true; break;case "green":primary=true; break;case "blue":primary=true; break; default:primary=false;
}
if (primary) System.out.println("This is a primary color");
讓我們最后以解決我們(可以這么說)問題的最面向對象的解決方案作為結尾。 Java枚舉主要是類,因此可以像其他任何類一樣具有方法和字段。 通過應用Template Method設計模式 ,可以定義一種抽象方法(對測試進行建模),該方法必須由所有子類實現(對應用于枚舉的特定項的測試響應進行建模):
Color c = Color.valueOf("RED");
if ( c.isPrimaryColor() ) {System.out.println("This is a primary color");
}public enum Color {RED() {@Override public boolean isPrimaryColor() {return true;}},BLUE() {@Override public boolean isPrimaryColor() {return true; }},YELLOW() {@Override public boolean isPrimaryColor() {return true; }};GREEN() {@Override public boolean isPrimaryColor() {return false; }};public abstract boolean isPrimaryColor();
}
生成的代碼是清晰的并且具有自我說明性。 在許多情況下,使用此模式可以替代更常見的“ if – else if”邏輯,因為它更易于閱讀,擴展和維護。
總而言之,我想說,對于一個問題,在很多情況下(就實現而言),存在著許多不同的解決方案,而這正是Java語言的強大功能。 但是,決定哪個最好是另一個故事……
參考: 簡短但正確! 來自我們的W4G合作伙伴 Bernard Ligny 。
相關文章 :
- Java中的低GC:使用原語而不是包裝器
- Java Lambda語法替代
- JVM如何處理鎖
- Java Fork / Join進行并行編程
- Java最佳實踐系列
- 如何在Java中獲得類似于C的性能
翻譯自: https://www.javacodegeeks.com/2011/09/do-it-short-but-do-it-right.html