词条 | 魔数 |
释义 | 很多类型的文件,其起始的几个字节的内容是固定的(或是有意填充,或是本就如此)。根据这几个字节的内容就可以确定文件类型,因此这几个字节的内容被称为魔数 (magic number)。此外在一些程序代码中,程序员常常将在代码中出现但没有解释的数字常量或字符串称为魔数 (magic number)或魔字符串。 魔数1所谓魔数和魔字符串就是指在代码中出现但没有解释的数字常量或字符串。如果在某个程序中你使用了魔数,如果在几个月(或几年)后你将可能不知道它的含义是什么。 譬如一个很简单的根据职位计算薪水的方法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)了。 咋一看,代码这样写也没有什么问题,但是,仔细思考一下就会发现,如果这种随手捻来的字符串和数字散布于程序当中,随处可见的话,是会有很多弊病的。我们先来分析三个魔字符串。虽然三个Magic String的意义很明显,并不影响到代码的可读性,但是这样却增加了出错的概率,并且忽略了具体的语义环境。我们很容易就会想到,像"Programmer"这个单词散布在多个方法中,一个大小写的笔误就会产生bug。同时,"Programmer"在计算薪水的方法中代表着职位,但是在统计公司订阅的杂志的方法中,也许就要代表一本杂志的名称了。然而这种语义环境是无法通过一个单纯的"Programmer"就能体现出来的。 Magic Number而Magic Number的问题就更大了,首先是影响了代码的可读性,谁会知道500和800是薪水基数,700是补贴呢?而且更糟糕的是,如果薪水基数发生改变的时候,那么就得找人把这些500,700,800的数字找出来一个一个地update,那可是一件够郁闷的事情了。 如果我们拥有一个常量定义的interface,代码就会变漂亮起来了: 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; } 从以上的分析,在一个Project里面,避免使用魔数(Magic Number)和魔字符串(Magic String)是相当必要的。通过定义的常量去access特定的字符串和数字也已经是软件开发的standard。那么是不是所有的数字和字符串都应该定义成常量呢?或许有朋友会认为所有的数字和字符串都应该定义成常量,但是我觉得,每个字符串确实是应该定义成常量的,但是对于数字而言,如果数字本身的语义没有得到延伸,那么就不应该定义成常量。譬如数组的index就不应该定义成变量。 像这样的代码: 代码String building = address[Constants.ONE]; // 在Constants这个interface中,ONE的定义为 final int ONE = 1; 你一定会觉得这样的代码就是画蛇添足, 因为ONE就是1,它没有其他特别的含义,不像上面代码中的500和700。而且如果真的要这样定义的话,出现了有上百个元素的数组的时候,那么你就得定义上百个没有任何意义的常量了。是不是很FT呢? 在程序中除了0,1,2这几个有特殊用处的数字,其它的都要声明为常量。总之,任何策略的使用,还是一个度最重要。 魔数2很多类型的文件,其起始的几个字节的内容是固定的(或是有意填充,或是本就如此)。因此这几个字节的内容也被称为魔数 (magic number),因为根据这几个字节的内容就可以确定文件类型。 例如 1)FreeBSD 上 ELF 文件的 magic number 就是文件的前四个字节依次为"7f 45 4c 46",对应的ascii字符串即 "^?ELF"。 2)tar 文件的 magic number 是从第257个字节起为 "ustar"。 3)PE文件中,在DOS-根之后是一个32位的签名以及魔数0x00004550 (IMAGE_NT_SIGNATURE)(意为“NT签名”,也就是PE签名;十六进制数45和50分别代表ASCII码字母P和E,它使任何PE文件都是一个有效的MS-DOS可执行文件。 Unix 命令 "file" 应该就是利用这个原理工作的。 核学魔数是稳定核素"幻数"的另称。 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。