<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:楷体_GB2312; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:"/@楷体_GB2312"; panose-1:2 1 6 9 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:modern; mso-font-pitch:fixed; mso-font-signature:1 135135232 16 0 262144 0;} @font-face {font-family:华文仿宋; panose-1:2 1 6 0 4 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:647 135200768 16 0 262303 0;} @font-face {font-family:"/@华文仿宋"; panose-1:2 1 6 0 4 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:647 135200768 16 0 262303 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} p {mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:宋体; mso-bidi-font-family:宋体;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} -->
一、关键字与标识符
1-1 、关键字不能被用作类、变量、方法或者其他任何内容的标识符。
1-2 、所有关键字都以小写字母开头。
1-3 、关键字是发展变化的。jdk1.5 中加入了enum 枚举关键字。
1-4 、true 、fasle 、null 、const 以及goto 不是关键字,但也不能用作标识符。如:boolean const = true; 是不能编译的。
1-5 、不要把Java 的关键字和其他语言混淆了。如:C++ 的include 、unsigned 等。
1-6 、标识符由字母、数字、下划线(_) 、美元符号($) 、人民币符号 ( ¥) 组成,并且第一个字符不能是数字,也不能把JAVA 中的关键字和保留关键字作为标识符。另外,标识符可以使用汉字、日文片假名等Unicode 字符,如:boolean 吃饱了吗 = true; 。Unicode 字符集的前128 个是ASCII 码表。
二、常量和所有原始数据类型的范围
2-1 、基本类型的存储空间。byte--8 位,short--16 位,int--32 位,long--64 位,float--32 位,double--64 位。这六种数字类型都是有符号的。固定的存储空间正是Java 可移植性、跨平台的原因之一!
2-1 、基本类型的存在导致了Java OOP 的不纯粹性。因为基本类型不是对象,一切皆对象是个小小的谎言。这是出于执行效率的权衡。
2-2 、使用公式-2 的(位数-1 )次幂到2 的(位数-1 )次幂-1 确定整数类型的范围(byte 、short 、int 、long )。
2-3 、char 是16 位Unicode 字符或者说是16 位无符号整数,范围从0 到65535 。即便如此,可以强制转换非法的数据,如:char c1 = (char) 10000; char c2 = (char) -200; 。可以从二进制存储的角度理解这点。
2-4 、整数有八进制(以0 开头的整数)、十进制、十六进制(以0x 或0X 开头的整数)表示。
2-5 、char 可以用单引号表示单个字符,如:' 良' 。也可以用unicode 值'"ucafe' (四位十六进制数)。
2-6 、布尔型boolean 。布尔型只能是true 或者false ,并且测试它为真还是假。它不能进行任何其他的运算,或者转化为其他类型。
正例:boolean b1 = 1 > 2; 反例:int seen = button.isVisible();
实践:简洁是美德,请不要这样写:if ( is == true && done == false ) ,只有新手才那么写。
对于任何程序员 if ( whether && !done ) 都不难理解吧。所以去掉所有的==fasle 和 ==true 。
2-7 、默认的浮点类型是双精度(double ),要想要一个float 必须在浮点数后面加F 或者f 。如:float pi = 3.14; 是错误的。
2-7 、默认的整数类型是int 型,要想使用长整型可在后面加“l ”或“L ”,如:1000L 。(小写l 容易被误认为1 ,不推荐用)
2-8 、float 可以精确到7 位有效数字,第8 位的数字是第9 位数字四舍五入上取得的;double 可以精确到16 位有效数字,第17 位的数字是第18 位数字四舍五入上取得的。盖茨到底有多少钱?要用double 表示,用float 是装不下的……
2-9 、如果要求精确的答案,请不要使用float 和double ,因为它们是为了在广域数值范围上提供较为精确的快速近似运算而精心设计的。然而,它们没有提供完全精确的结果。尤其是对货币计算尤为不适合,因为要让一个float 或double 精确地表达0.1 (或者10 的任何)
2-10 、BigInteger 支持任意精度的整数。BigDecimal 支持任意精度的定点数。
2-11 、初始化无论怎么强调都不过分!Java 为所有的成员变量提供了默认初始化:byte 、short 、 int 、long--0 float--0.0f double--0.0 boolean--false char--'"u0000' ,特别地对象类型的引用全被初始化为null 。(注意!除了数组之外的局部变量是得不到这种优待的,需要你自己初始化。另外,默认初始化的值是你想要的吗?所以最好明确地对变量进行初始化,一般是在构造函数中。)
2-12 、基本类型之间的转化。Java 的类型检查很严格,从低精度转换到高精度是无须显式转换的,double d = 123; 。但是反过来,进行窄化转换,由高精度向低精度,或者一种类型到另一种类型,则必须使用强制类型转化。Java 提供了安全转化机制,但是结果是否是期望的,你自己保证吧。
double d = 12.5;
float f = (int) d; // 结果不是13 ,而是12 !
浮点型转化为整型时,不进行四舍五入,直接截断小数点后面的数。
2-13 、提升。各种基本数据类型进行混合运算,结果会是表达能力最强的那种。如:int 和long 运算,结果是long ,整型和浮点型运算结果是浮点型。特殊的一点是:只要类型比int 小(如char 、byte 、short ),那么在运算之前,这些值会自动地转换成int 。例子:
byte b1 = 12;
byte b2 = b1 + 1; // 在编译时出错了!因为b1+1 已经是int 型了!切记!
2-14 、浮点类型的科学表示法。在数学中e 代表自然对数(Math.E 给出了double 值),而在Java 中e 代表10 的幂次。浮点型的数可以这样表示float f = 1e-27f; 代表1 乘以10 的负27 次幂。
三、数组
3-1 、数组不是集合,它只能保存同种类型的多个原始类型或者对象的引用。(注意保存的是对象的引用,而不是对象本身。)
3-2 、数组本身就是对象,Java 中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
3-3 、数组声明的两种形式:一、int[] arr; 二、int arr[]; 推荐使用前者,这符合Sun 的命名规范,而且容易了解到关键点,这是一个int 数组对象,而不是一个int 原始类型。
3-4 、在数组声明中包含数组长度永远是不合法的!如:int[5] arr; 。因为,声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM 才分配空间,这时才与长度有关。
3-5 、在数组构造的时候必须指定长度,因为JVM 要知道需要在堆上分配多少空间。反例:int[] arr = new int[];
3-6 、多维数组的声明。int[][][] arr; 是三维int 型数组。
3-7 、一维数组的构造。形如:String[] sa = new String[5]; 或者分成两句:String[] sa; sa = new String[5];
3-8 、原始类型数组元素的默认值。对于原始类型数组,在用new 构造完成而没有初始化时,JVM 自动对其进行初始化。默认值:byte 、short 、 int 、long--0 float--0.0f double--0.0 boolean--false char--'"u0000' 。(无论该数组是成员变量还是局部变量)
3-9 、对象类型数组中的引用被默认初始化为null 。如:Car[] myCar = new Car[10]; 相当于从myCar[0] 到myCar[9] 都这样被自动初始化为myCar = null;
3-10 、对象类型的数组虽然被默认初始化了,但是并没有调用其构造函数。也就是说:Car[] myCar = new Car[10]; 只创建了一个myCar 数组对象!并没有创建Car 对象的任何实例!
3-11 、多维数组的构造。float[][] ratings = new float[9][]; 第一维的长度必须给出,其余的可以不写,因为JVM 只需要知道赋给变量ratings 的对象的长度。
3-12 、数组索引的范围。数组中各个元素的索引是从0 开始的,到length-1 。每个数组对象都有一个length 属性,它保存了该数组对象的长度。(注意和String 对象的length() 方法区分开来,这两者没有统一起来是很遗憾的。)
3-13 、Java 有数组下标检查,当访问超出索引范围时,将产生ArrayIndexOutOfBoundsException 运行时异常。注意,这种下标检查不是在编译时刻进行的,而是在运行时!也就是说int[] arr = new int[10]; arr[100] = 100; 这么明显的错误可以通过编译,但在运行时抛出!Java 的数组下标检查是需要额外开销的,但是出于安全的权衡还是值得的,因为很多语言在使用数组时是不安全的,可以任意访问自身内存块外的数组,编译运行都不会报错,产生难以预料的后果!
四、运算符和表达式
4-1 、不要记操作符的优先级。用括号的可读性更好,也节省你的脑细胞。
4-2 、操作符可能会改变操作数的自身的值,这被称为副作用。涉及赋值的语句肯定具有副作用了,另外两个是前缀和后缀式的“++ ”“-- ”。副作用不是贬义的词,看看它的概念就知道了。
4-3 、关于对象的比较。
“== ”比较的是两个引用是否指向同一个对象,注意是引用的比较,不是对象的比较。equals() 方法是Object 对象的一个方法,也就是说所有的对象都中继承了equals() 方法。按照常理,我们通常会覆盖equals() 方法,在其中加入我们认为两个对象的内容相同的条件,然后a.equals(b) ,比较的是内容了。但是如果你建立了新类,而且没有覆盖equals 方法,那么equals 比较的仍然是引用!因为equals 的默认行为是比较引用。这点要注意了!Java 类库中一般都覆盖了equals 方法。
4-4 、&& 和|| 与 & 和| 的比较。相同点:都可以用在布尔表达式中。不同点:前者支持短路运算,后者不支持。
实践:短路运算能带来潜在的性能提升,该用哪个不必多言了吧。
………………
五、类声明和修饰符
5-1 、每个源文件只能有一个public 类,也可以没有。
5-2 、如果有public 类,那么该源文件的文件名必须和public 类的名字一致;如果没有public 类,该源文件的名字可以是任意的。
5-3 、包语句(pagage )必须第一行;导入语句(import )必须放在包语句和类声明之间。如果没有包语句,则导入语句必须第一行。(注释、空行不计算在内)
5-4 、Java 有3 种访问控制修饰符:public 、protected 和private 。有4 种访问级别,按访问控制的严格程度由小到大:public 、protected 、默认和private 。
5-5 、类的访问级别只有两种:public 和默认。具有public 访问级别的类能够被所有包中的所有类看到;具有默认访问级别的类只能被它所在的同一个包中的类访问。
5-6 、除访问修饰符外,类也能被修饰为final 、abstract 、或strictfp 。final 类不能被继承,abstract 类不能被实例化,strictfp 类的所有表达式中的浮点数将遵守IEEE754 标准。
5-7 、类不能同时被修饰为final 和abstract ,两者具有相反的含义。
5-8 、类中只要有一个方法被修饰为abstract 的,它所在的类就必须被修饰为abstract 的。
5-9 、abstract 类可以有抽象方法,也可以有非抽象方法。
5-10 、继承abstract 类的第一个具体类必须实现所有的abstract 方法