1、字符串即使不会再被用到,这个字符串也不会被垃圾回收,因为它将一直存放于字符串中,这也是Java内存泄漏的原因之一。
2、复合复制运算符(+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=)包含隐式转换。
比如:short value = 5;
value = value -2; //编译错误
value
-= 2; //编译通过,等价于value = (short)(value-2);
一般地:E1 op= E2 等价于: E1 = (E1的类型)(E1 op E2)
3、String提供的split(String
regex)方法需要的参数是正则表达式,所以在分割的时候,要注意特殊字符的表示(要对特殊字符进行转义),比如".", "+",
"?", "|"等。
4、同步代码
1)对于同步代码块而言,程序必须显式地为它指定同步监视器;
2)对于同步非静态方法而言,该方法的同步监视器是this,即调用该方法的Java对象;
3)对于静态的同步方法而言,该方法的同步监视器不是this,而是该类本身。
5、switch中的case分支访问枚举值时不能使用枚举类名作为限定。
6、Java语言规定:for,
while或do/while循环中的重复执行语句不能是一条单独的局部变量定义语句;如果程序要使用循环来重复定于局部变量,这条局部变量定义语句必须放在花括号内才有效。
比如:for(int i=0;i<10;i++)
String str = “test"; //不允许
7、for循环的初始条件可以同时定义多个变量,但由于它只能接受一条语句,因此这两个变量的数据类型应该相同。
8、当使用foreach循环来迭代输出数组元素或者集合元素时,系统将数组元素、集合元素的副本传给循环计数器,foreach循环中的循环计数器并不是数组元素、集合元素本身。
9、instanceof运算符前面操作数的编译时类型必须是如下三种情况:
1)要么与后面的类相同;
2)要么是后面类的父类;
3)要么是后面类的子类;
例如:
Object str = "test";
Math math = (Math)str; //强制转换,讲解见10
System.out.println(math instanceof String); //编译不通过,因为math的编译时类型是Math,它既不是String的父类,也不是子类,更不是String类型,所以无法通过编译。
10、Java的强制转换
在编译阶段,强制转换要求被转换变量的编译时类型必须是如下三种情况之一:
1)被转换变量的编译时类型与目标类型相同;
2)被转换变量的编译时类型是目标类型的父类;
3)被转换变量的编译时类型是目标类型的子类。这种情况下可以自动向上转换,无需强转。
在运行节点,被转换变量所引用的对象必须是目标类型的实例,或者是目标类型的子类、实现类的实例,否则在运行时将引发ClassCastException异常。
注意:null instanceof String,返回false。
11、java构造方法并不会创建对象,它支付者执行初始化,在构造方法执行之前,Java对象所需要的内存空间,应该说是有new关键字申请出来的。
大多数情况下,程序使用new关键字为一个Java对象申请空间之后,都需要使用构造方法对这个对象执行初始化,但在某些时候,程序创建对象无须调用构造方法:
1)使用反序列化的方式恢复Java对象;
2)使用clone方式复制Java对象。
12、系统在编译阶段总会为非静态内部类的构造方法增加一个参数,非静态内部类的构造方法的第一个形参总是外部类。因此调用非静态内部类的构造方法时必须传入一个外部类对象作为参数,否则程序将会引发运行时异常。
13、非静态内部类不能拥有静态成员。