《編寫高質量代碼:改善Java程序的151個建議》的一些筆記

一、int 最大值爲2147483647,若計算溢出,則結果爲負值。java

如,2147483647+1,結果爲-2147483648。apache

因此,若是一個方法接收的是int 類型的參數,那如下三個值是必測的:0、正最大、負最小,其中正最大和負最小是邊數組

界值。dom

二、包裝類型的比較大小
ide

Integer i = new Integer(100);
Integer j = new Integer(100);
System.out.println(i == j);   //false
System.out.println(i > j);    //false
System.out.println(i < j);    //false

在Java 中「==」是用來判斷兩個操做數是否有相等關係的,若是是基本類型則判斷值是否相等,若是是對象則判斷是不是一個對象的兩個引用,也就是地址是否相等,這裏很明顯是兩個對象,兩個地址,不可能相等。工具

因此,比較包裝類型的大小,用compareTo 方法,相等返回0,小於返回-1,大於返回1。ui

三、隨機數
spa

在Java 中有兩種方法能夠得到不一樣的隨機數:經過java.util.Random 類獲得隨機數的原理和Math.random 方法相同,Math.random() 方法也是經過生成一個Random類的實例,而後委託nextDouble() 方法的。code

Random類的默認種子(無參構造)是System.nanoTime() 的返回值(JDK 1.5 版本之前默認種子是System.currentTimeMillis() 的返回值)對象

隨機數的產生取決於種子,隨機數和種子之間的關係聽從如下兩個規則:a、種子不一樣,產生不一樣的隨機數。b、種子相同,即便實例不一樣也產生相同的隨機數。

因此,若非必要,不要設置隨機數種子。


四、靜態變量

靜態變量是在類初始化時首先被加載的,JVM 會去查找類中全部的靜態聲明,而後分配空間,這時候只是完成了地址空間的分配,尚未賦值,以後JVM 會根據類中靜態賦值(包括靜態類賦值和靜態塊賦值)的前後順序來執行。

static {
		i = 100;
	}
	public static int i = 1;
	public static void main(String[] args) {
		System.out.println(i); //結果爲1
	}

public static int i = 1;
	static {
		i = 100;
	}
	public static void main(String[] args) {
		System.out.println(i); //結果爲100
	}

靜態變量是類加載時被分配到數據區(Data Area)的,它在內存中只有一個拷貝,不會被分配屢次,其後的全部賦值操做都是值改變,地址則保持不變。

五、靜態方法

實例對象有兩個類型:表面類型(Apparent Type)和實際類型(ActualType),表面類型是聲明時的類型,實際類型是對象產生時的類型。

靜態方法不依賴實例對象,它是經過類名訪問的;其次,能夠經過對象訪問靜態方法,如果是經過對象調用靜態方法,JVM 則會經過對象的表面類型查找到靜態方法的入口,繼而執行之。

public class StaticMethod {
	public static void main(String[] args) {
		Base base = new Sub();
		// 調用非靜態方法
		base.doAnything();    //結果,我是子類非靜態方法
		// 調用靜態方法
		base.doSomething();   //結果, 我是父類靜態方法 
	}
}
class Base{
	// 父類靜態方法
	public static void doSomething(){
		System.out.println(" 我是父類靜態方法");
	}
	// 父類非靜態方法
	public void doAnything(){
		System.out.println(" 我是父類非靜態方法");
	}
}
class Sub extends Base{
	// 子類同名、同參數的靜態方法
	public static void doSomething(){
		System.out.println(" 我是子類靜態方法");
	}
	// 覆寫父類的非靜態方法
	@Override
	public void doAnything(){
		System.out.println(" 我是子類非靜態方法");
	}
}

六、構造代碼塊

public class Client {
    {
        // 構造代碼塊
        System.out.println(" 執行構造代碼塊");
    }
    public Client(){
        System.out.println(" 執行無參構造");
    }
    public Client(String _str){
        System.out.println(" 執行有參構造");
    }
}

至關於

public class Client {
    public Client(){
        System.out.println(" 執行構造代碼塊");
        System.out.println(" 執行無參構造");
    }
    public Client(String _str){
        System.out.println(" 執行構造代碼塊");
        System.out.println(" 執行有參構造");
    }
}

七、若是一個類不容許實例化,就要保證「日常」渠道都不能實例化它。

public class UtilsClass {
    private UtilsClass(){
        throw new Error(" 不要實例化我! ");
    }
}

八、淺拷貝

 Object 提供了一個對象拷貝的默認方法clone(),實現Cloneable 接口就具有了拷貝能力,拷貝規則以下:

(1)基本類型,若是變量是基本類型,則拷貝其值,好比int、float 等。

(2)對象,若是變量是一個實例對象,則拷貝地址引用

(3)String 字符串,這個比較特殊,拷貝的也是一個地址,是個引用,可是在修改時,它會從字符串池

(String Pool)中從新生成新的字符串,原有的字符串對象保持不變,在此處咱們能夠認爲String 是一個基本類型。

九、hashCode

Map 的底層處理機制是以數組的方式保存Map 條目(Map Entry)的,這其中的關鍵是這個數組下標的處理機制:依據傳入元素hashCode 方法的返回值決定其數組的下標,若是該數組位置上已經有了Map 條目,且與傳入的鍵值相等則不處理,若不相等則覆蓋;若是數組位置沒有條目,則插入,並加入到Map 條目的鏈表中。同理,檢查鍵是否存在也是根據哈希碼肯定位置,而後遍歷查找鍵值的。

Set  集合是按hashCode來判斷對象是否相等。

HashCodeBuilder 是org.apache.commons.lang.builder 包下的一個哈希碼生成工具。

相關文章
相關標籤/搜索