第45條:將局部變量的做用域最小化java
1.要是局部變量的做用域最小化,最有力的方法就是在第一次使用它的地方進行聲明安全
2.每一個局部變量的聲明都應該包含一個初始化的表達式,若是沒有一個肯定的值,能夠賦值nullide
3.局部變量的做用域應該是從它聲明的地方開始,一直到外圍塊(block)結束,這樣能夠避免發生意想不到的意外性能
eg:ui
Set<String> set = new TreeSet<String>(); Iterator<String> iterator1 = set.iterator(); while (iterator1.hasNext()) { System.out.println("dosomething..."); } Set<String> set2 = new TreeSet<String>(); Iterator<String> iterator2 = set.iterator(); while (iterator1.hasNext()) { System.out.println("dosomething..."); }
對於複製-粘貼性的代碼,在第二個循環中就包含了一個隱含的錯誤,緣由在於iterator1 的做用域還在有效範圍以內,它能夠經過編譯,從而致使在程序運行期間發生不可意料的錯誤。線程
相反,若是是經過for-each循環來完成這件事,就不會出現上述的意外,由於str的做用域只在屬於它的塊(block)中有效指針
for (String str : set) { System.out.println("dosomething..."); } for (String str : set2) { System.out.println("dosomething..."); }
第46條code
for-each循環優先於傳統的for循環對象
eg:作用域
public class Test { enum test1{ONE,TWO,THREE,FROU} enum test2{ONE,TWO,THREE,FROU,FIVE,SIX} public static void main(String[] args) { Collection<test1> c1 = Arrays.asList(test1.values()); Collection<test2> c2 = Arrays.asList(test2.values()); Map<Object, Object> map = new HashMap<Object, Object>(); for (Iterator<test1> i = c1.iterator();i.hasNext();) { for (Iterator<test2> i2 = c2.iterator();i2.hasNext();) { map.put(i.next(), i2.next()); } } } }
若是使用上面的迭代器進行集合循環遍歷,在兩層循環的狀況下,上面的程序會拋出
Exception in thread "main" java.util.NoSuchElementException
緣由是在第二層循環中,重複調用了i.next();這個方法每調用一次,迭代器的指針就會日後移動一位,由於第二個集合的大小要比第一個集合的大小要大,因此到最後會找不到元素致使拋出異常
因此針對這種狀況應該要用for-each循環會比較合適。
(在實際的開發過程當中也遇到過相似的狀況,在循環中重複的調用iterator.next()致使程序異常)
若是是單層循環的狀況,你堅持要用iterator進行遍歷的話,建議將iterator.next()的值放入到一個臨時變量中
須要提出的是上述的兩種循環方式性能相差無幾。甚至比起普通的for循環,for-each循環還稍有優點。
第47條:瞭解和使用類庫
..........
第48條:若是須要精確的xx,請避免使用float和double
...後續再舉例補充
第49條:基本類型優先於裝箱基本類型
1.每一個基本類型都有一個對應的引用類型,稱之爲裝箱基本類型,好比int、double、boolean對應的裝箱類型就是Integer、Double、Boolean
2.基本類型和裝箱類型的主要區別。
1、基本類型只有值,裝箱基本類型除了它對應的值以外,還有個非功能值null
2、基本類型一般比裝箱類型更節省時間和空間
好比說int的默認值是0,而Integer的默認值爲null
我的以爲區分基本類型和裝箱的基本類型最重要的裝箱基本類型表明的是一個對象的引用,這點在判斷對象/值是否相等的時候有着很大的不一樣
eg:
public static void main(String[] args) { Comparator<Integer> naturalOrder = new Comparator<Integer>() { @Override public int compare(Integer first, Integer second) { return first < second ? -1 : (first == second ? 0 : 1); } }; System.out.println(naturalOrder.compare(21, 21)); System.out.println(naturalOrder.compare(new Integer(21), new Integer(21))); }
上面會分別輸出:0,1,究其緣由,first和second表示的是擁有同一個int值得不一樣實例,用==比較則會返回false
若是要改進上面的方法,只須要在內部添加兩個基本類型來保存first、second的值便可
int f = first;
int s = second;
return f < s ? -1 : (f == s ? 0 : 1);
另一個比較常見的問題就是若是下面這種狀況
public static void main(String[] args) { Integer value = null; while (value < 10) { System.out.println("..."); } }
由於裝修基本類型的默認值爲null,當在沒有值的狀況下,使用它,則會拋出NullPointException,相反,若是使用基本類型,則不會出現這種異常狀況
第50條:若是其餘類型更合適,則儘可能避免使用字符串
........
第51條:擔憂字符串鏈接的性能
對於重複性的往字符串中拼接值進去的狀況,要避免使用String,由於會致使性能問題,緣由是String是不可變的字符串,每次拼接時,他們的內容都要被拷貝,即每拼接一次都會產生一個新的對象。代替的是StringBuffer、StringBuilder,其中StringBuffer爲線程安全的,StringBuilder爲非線程安全的。