這是一個知識點,Java中的「魔數「

在編程過程中,我們可能經常聽到“魔數”這個詞,那麼這個詞到底指的是什麼呢?什麼數叫做魔數呢?

一、標識文件類型的“魔數”

大多數情況下,我們都是通過擴展名來識別一個文件的類型的,比如我們看到一個.txt類型的文件我們就知道他是一個純文本文件。但是,擴展名是可以修改的,那一旦一個文件的擴展名被修改過,那麼怎麼識別一個文件的類型呢。這就用到了我們提到的“魔數”。

很多類型的文件,其起始的幾個字節的內容是固定的(或是有意填充,或是本就如此)。因此這幾個字節的內容也被稱為魔數 (magic number),因為根據這幾個字節的內容就可以確定文件類型。有了這些魔術數字,我們就可以很方便的區別不同的文件。

為了方便虛擬機識別一個文件是否是class類型的文件,SUN公司規定每個class文件都必須以一個word(四個字節)作為開始,這個數字就是魔數。魔數是由四個字節的無符號數組成的,而class文件的名字還挺好聽的的,其魔數就是0xCAFEBABE

讀者可以隨便編譯一個class文件,然後然後用十六進制編輯器打開編譯後的class文件,基本格式如下:

這是一個知識點,Java中的“魔數“

如何使用16進制打開class文件:使用 vim test.class ,然後在交互模式下,輸入:%!xxd 即可。

二、代碼中的魔數

在有些代碼中,有一些數字常量或者字符串,他們沒有註釋,並且從命名上也看不出什麼意思,很可能在過一段時間之後誰也不知道這個常量或者字符串代表什麼意思。我們就稱這個常量或者字符串為魔數。

在《阿里巴巴Java開發手冊》中也有關於魔數的要求:

這是一個知識點,Java中的“魔數“

所有需要使用魔數的地方,都可以使用枚舉或者靜態變量來代替。譬如一個很簡單的根據職位計算薪水的方法:

public int getSalary(String title, int grade) {

if ("Programmer".equals(title)){

return grade 500 + 700;

}

else if ("Tester".equals(title)){

return grade 500 + 800;

}

else if ("Analyst".equals(title)){

return grade 800 + 1000;

}

}

在這個方法裡面,”Programmer”,”Tester”和”Analyst”是所謂的魔字符串(Magic String),而500, 700,800和1000就是所謂的魔數(Magic Number)了。 咋一看,代碼這樣寫也沒有什麼問題,但是,仔細思考一下就會發現,如果這種隨手捻來的字符串和數字散佈於程序當中,隨處可見的話,是會有很多弊病的。

如果我們使用常量來代替上面的魔數的話,代碼就會清爽很多,而且,下次修改的時候只需要修改常量值就可以了。

public int getSalary(String title, int grade) {

if (Constants.TITLE_PROGRAMMER.equals(title)){

return grade Constants.BASE_SALARY_LOW + Constants.ALLOWANCE_LOW;

}

else if (Constants.TITLE_TESTER.equals(title)){

return grade * Constants.BASE_SALARY_LOW + Constants.ALLOWANCE_MEDIUM;

}

else if (Constants.TITLE_ANALYST.equals(title)){

return grade * Constants.BASE_SALARY_HIGH + Constants.ALLOWANCE_HIGH;

}

}

在代碼中使用魔數,不僅使代碼的可讀性大大降低,還可能導致各種問題。所以在代碼中,我們要儘量避免產生魔數。

這是一個知識點,Java中的“魔數“

這是一個知識點,Java中的“魔數“


分享到:


相關文章: