建議1:
不要在常量和變量中出現容易混淆的字母:如long i = 1L,表示long類型,後面的l最好大寫
建議2:
不要讓常量蛻變成變量,常量應該在編譯期就確定。
如:publicstatic final int RAND_CONST = new Random().nextInt();
建議3:
三元操作符的類型務必一致
如:
public class Suggest3 {
public static void main(String[] args) {
int i = 80;
String s = String.valueOf(i < 100 ? 90 : 100);
// 100.0爲float類型,返回值時,90會被自動提升爲90.0,所以兩個String不是同一個對象
String s1 = String.valueOf(i < 100 ? 90 : 100.0);
System.out.println(s == s1);
/*
* 上面提到三元運算符的一個類型轉換問題
* 1,若兩個操作數不可轉換,則不轉換,返回Object
* 2,若連個數都是明確的表達式,則int轉long,long轉float
* */
}
}
建議4:
使用變長方法時,避免帶有變長參數的方法重載:
如:
public class Suggest4 {
public static void main(String[] args) {
// 執行的是簡單折扣的方法,雖然多次折扣的方法也包括了改參數類型
// 最好不要用,容易引起混淆
calPrice(100, 75);
calPrice(100, 75, 80);
}
public static void calPrice(int price, int discount) {
float money = price * discount / 100.0F;
System.out.println("折扣後的價是:" + money);
}
// 方法重載 ,傳入可變長參數
public static void calPrice(int price, int... discount) {
float money = price;
for (int d : discount) {
money = money * d / 100.0F;
}
System.out.println("多次折扣後的價是:" + money);
}
}
建議5:
警惕自增的陷阱:
看下面這段代碼
public class Suggest5 {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < 10; i++) {
// count++是一個表達式,返回count自加前的值
count = count++;
}
System.out.println(count);
}
}
輸出count的值是0
建議6:
避免instanceof非預期結果
//詳細分析instanceof()
public class Suggest6 {
public static void main(String[] args) {
// 判斷String對象是否是Object對象的實例
// true
boolean b1 = "cloud" instanceof Object;
// String對象是否是String的實例
// true
boolean b2 = new String() instanceof String;
// Object對象是否是String的實例
// false,Object是String的父類,編譯可以通過
boolean b3 = new Object() instanceof String;
// 拆箱類型是否是裝箱類型的實例,編譯不通過,char類型是基本類型,instanceof只用於對象的判斷
// boolean b4 = 'A' instanceof Character;
// 空對象是否是String的實例
// false,規則:如果左操作數是null,則直接返回false不再運算右邊
boolean b5 = null instanceof String;
// 轉換類型後的null是否是String類型的對象
// false,null沒有類型,做類型轉換後還是null
boolean b6 = (String) null instanceof String;
// Data對象是否是String對象的實例,編譯不通過,Date類和String沒有繼承或實現關係
// boolean b7 = new Date() instanceof new String;
}
}
建議7:
使用偶判斷,不用奇判斷
如下面:可看到-1也是偶數
底層運算公式是: dividend表示被除數-1,divisor表示除數2
dividend– dividend/divisor * divisor
所以最好用偶判斷
建議8:
在接口中不要存在實現代碼
如下:
//接口中可以聲明常量,聲明抽象方法,也可繼承父接口
interface B {
// 聲明一個S類型的常量,指向匿名對象
public static final S s = new S() {
public void doSomething() {
System.out.println("在接口中實現了");
}
};
}
interface S {
public void doSomething();
}
public class Suggest8 {
public static void main(String[] args){
B.s.doSomething();
}
}
使用String字符串的一些建議:
建議9:
推薦使用String直接量賦值,如:String str = “abcd”;
代碼如下:
public class Suggest9 {
public static void main(String[] args) {
String str1 = "itheima";
String str2 = "itheima";
String str3 = new String("itheima");
String str4 = str3.intern();
// true,這裏用到了一個字符串池的技術,主要爲了避免產生大量String對象
// 在使用直接量賦值時,會先檢查字符串池中有沒有相等的值,有就不再創建對象,而是返回池中的對象引用
System.out.println(str1 == str2);
// false,new String不會檢查字符串池,而是直接創建一個新對象,也不會把對象放入字符串池中
System.out.println(str1 == str3);
// true,intern()方法會檢查池有沒有值相同的對象,有就放回池中對象的引用,沒有就將當前對象放入池中,並返回當前對象
System.out.println(str1 == str4);
}
}
String類是一個不可變(Immutable)對象
1,String類是final修飾的,不可繼承,不可能產生一個String的子類
2,在String提供的方法中,如果有String返回值,就會新建一個String對象,不對原對象進行修改
所以不會產生線程安全問題
建議10:
使用String,StringBuffer,StringBuilder的場景
1,String
在字符串不經常變化的場景中可以使用String類,例如:常量的聲明,少量的變量運算
2,StringBuffer(線程同步)
在頻繁進行字符串的運算(如拼接,替換,刪除),並且運行在多線程的環境中,如XML解析,HTTP參數解析和封裝等
3,StringBuilder(線程不同步)
在頻繁進行字符串的運算(如拼接,替換,刪除),並且運行在單線程的環境中,如SQL語句的拼裝,JSON封裝等