我们知道,Java中的每个类都有构造方法,无论是系统自动提供的空的构造方法,还是自己定义的有参数的构造方法,其作用都是完成对象的创建及初始化,构造方法有以下特征:
(1)没有返回值;
(2)方法名与类名相同;
(3)不能在构造方法中出现return语句;
除此之外,还有一些我们必须知道的东西:
(1)构造方法不能用void修饰:
我们在定义没有返回值的方法时会使用void关键字,但是作为强类型语言,使用void修饰没有返回值的方法也说明
void是一种数据类型,即表示"没有返回值"(有点绕,可以理解为返回值类型为空)...
Java中的数据分为基本类型与引用类型,首先可以排除的是它肯定不是引用类型数据;八种基本类型中并不包括void。
java.lang包中存在一个"Void类",描述如下:
public final class Void {
/**
* The {@code Class} object representing the pseudo-type corresponding to
* the keyword {@code void}.
*/
@SuppressWarnings("unchecked")
public static final Class<Void> TYPE = (Class<Void>) Class.getPrimitiveClass("void");
/*
* The Void class cannot be instantiated.
*/
private Void() {}
}
不难看出Void类和String类一样被定义为final,所以不能扩展;另外,它的构造方法被私有化了所以不可实例化。
Void类是一个不可实例化的占位符类,用来保存一个引用代表了Java关键字void的Class对象。
由此可以得出"没有返回值"和"返回值为空"其实不是一回事,所以构造方法是不能用void修饰的。
(2)构造方法可以被任何表示访问权限的修饰符修饰,如public、private等;并且构造方法不能有任何非访问性质的修饰符
修饰,如:static、synchronized、final等(具体原因我们可以结合各个关键字的作用以及构造方法的本意进行思考);
(3)构造方法中可以调用类中的非静态方法,但是该方法必须被private或者final修饰:
当我们在构造子类时,会先调用父类的构造方法,而如果父类的构造方法中调用了父类中的方法,且该方法在子类中
被重写,因为多态特性,父类构造器实际上调用的是子类中被重写后的方法;
如果重写后的方法中调用了子类中的成员,而该子类中的成员在父类构造器执行被调用时还未来得及初始化成员变量
(该成员变量会在子类构造器调用之前执行),这会导致抛出空指针异常等等后果。
//父类
public class ParentClass {
public ParentClass() {
System.out.println("父类构造器执行!");
this.test();
}
public void test(){
System.out.println("父类中的方法!");
}
}
//子类
public class ChildClass extends ParentClass {
private Date date = new Date();
@Override
public void test(){
System.out.println("子类重写父类中方法:" + date.toString());
}
}
//测试类
public class Test {
public static void main(String[] args){
ParentClass demo = new ParentClass();
ChildClass child = new ChildClass();
}
}
//测试结果