1. 无限递归的构造器
在一些情况下,程序可能导致构造器无限递归,比如:
public class ConstrucorRecursion {
ConstrucorRecursion rc;
{
rc = new ConstrucorRecursion();
}
public ConstrucorRecursion() {
System.out.println("程序执行无参构造函数");
}
public static void main(String[] args) {
ConstrucorRecursion rc = new ConstrucorRecursion();
}
}
从表面上看,该程序似乎没有问题,构造器中只有一行输出代码,但是我们应该要知道,不管是定义实例变量时指定初始值,还是在非静态代码块中执行初始化操作,最终都将被提取到构造器中执行,最终导致了在构造器中再次执行了new ConstrucorRecursion()代码,导致递归,从而运行时报了java.lang.StackOverflowError异常
2. 方法重写的陷阱
(1). 重写private方法
对于使用private修饰符的方法,只能在当前类中使用该方法,子类无法访问父类用private修饰符修饰的方法。既然不能访问父类的private方法,当然也无法重写该方法了。对于在子类中定义了一个和父类private方法具有相同的方法名,相同参数列表,相同返回值类型的方法,依然不是重写,而是在子类中定义了一个新的方法而已
(2). 重写其他访问权限的方法
对于不使用访问控制符修饰的方法,表明它是包访问控制权限,它只能被与当前类处于同一个包内的其他类访问,其他包中的子类依然不能访问该方法,比如:package com.zhi.test1;
public class Animal {
void run() {
System.out.println("Animal中的run方法");
}
}
上面的run方法可能被重写:若子类与该类处于同一个package内,子类就可以重写run方法,否则不能被重写。下面的程序就不与Animal类处于同一包内,所以就不能重写Animal类中的run方法,只是重新定义了一个run方法而已
package com.tempfile_1;
public class Wolf extends com.zhi.test1.Animal {
private void run() {
System.out.println("Wolf中的run方法");
}
}
3. static关键字
对于static我们只需要记住一句话:被static关键字修饰的成员(Field,方法,内部类,初始化块,内部枚举类)属于类本身,而不是单个的java对象。具体到静态方法也是这样,静态方法属于类,而不是java对象
从下面一个程序中我们可以理解这句话:
class Animal {
public static void info() {
System.out.println("Animal类中的info方法");
}
}
@SuppressWarnings("static-access")
public class Wolf extends Animal {
public static void info() {
System.out.println("Wolf类中的info方法");
}
public static void main(String[] args) {
Animal a1 = new Animal();
a1.info();
Animal a2 = new Wolf();
a2.info();
Animal a3 = null;
a3.info();
}
}
结果输出3个同样的值:Animal类中info方法
从上面的程序中,我们一开始可能认为应该输出:Animal类中info方法 Wolf类中info方法,因为应该表现出new的对象中的info方法,但是我们要记住的是:上面的info是静态方法,而静态方法是属于类的,而不是属于对象的,上面的程序中a1,a2,a3调用info时,实际上都会委托声明a1,a2,a3的类来执行,也就是Animal来执行info方法