不解释自己看:
父类:Person
public class Person{
String name;
int age;
{
System.out.println("父类的非静态代码块");
}
static{
System.out.println("父类的static代码块");
}
Person(){
System.out.println("父类的无参构造函数");
}
Person(String name,int age){
this.name=name;
this.age=age;
System.out.println("父类的有参构造函数");
}
void eat(){
System.out.println("父类的吃饭");
}
public static void main(String[] args){
System.out.println("父类主方法");
Person p = new Person();
p.eat();
}
}
子类:Student
public class Student extends Person{
int grade;
{
System.out.println("子类的非静态代码块");
}
static{
System.out.println("子类的static代码块");
}
Student(){
System.out.println("子类的无参构造函数");
}
Student(String name,int age){
System.out.println("子类的有参构造函数:"+name+","+age);
}
Student(String name,int age,int grade){
this.grade=grade;
System.out.println("子类的有参构造函数:"+name+","+age+","+grade);
}
void eat(){
System.out.println("子类的吃饭");
}
public static void main(String[] args){
System.out.println("子类主方法");
System.out.println("------------1-------------");
Student s1 = new Student();
System.out.println("------------2-------------");
Student s2 = new Student("霸王谷",20,120);
System.out.println("------------3-------------");
Person s3 = new Student();
System.out.println("------------4-------------");
Student s4 = new Student("意识流",99);
System.out.println("------------5-------------");
Person s5 = new Student("我来卖萌的",22);
System.out.println("--------------------------");
s1.eat();
s2.eat();
s3.eat();
s4.eat();
s5.eat();
}
}
执行结果:
父类的static代码块
子类的static代码块
子类主方法
------------1-------------
父类的非静态代码块
父类的无参构造函数
子类的非静态代码块
子类的无参构造函数
------------2-------------
父类的非静态代码块
父类的无参构造函数
子类的非静态代码块
子类的有参构造函数:霸王谷,20,120
------------3-------------
父类的非静态代码块
父类的无参构造函数
子类的非静态代码块
子类的无参构造函数
------------4-------------
父类的非静态代码块
父类的无参构造函数
子类的非静态代码块
子类的有参构造函数:意识流,99
------------5-------------
父类的非静态代码块
父类的无参构造函数
子类的非静态代码块
子类的有参构造函数:我来卖萌的,22
--------------------------
子类的吃饭
子类的吃饭
子类的吃饭
子类的吃饭
子类的吃饭
总结:
可以看出静态代码块是程序首先执行的,而且先执行父类再执行子类的,并且有几个对象只执行一次静态代码块。
其次是从程序主方法开始执行,再执行非静态代码块和无参构造函数,而且仍然是先执行父类再执行子类的。
如果子类含有有参的构造函数,那么执行子类的有参构造函数,就不执行子类的无参构造函数了,但同样要执行父类的无参构造函数。
看到这里你会发现,非静态代码块和静态代码块的区别在于非静态代码块和构造函数一样,需要创建一次对象就执行一次的。
随后执行子类的成员函数,如果子类的成员函数重写了父类的成员函数,则只执行子类的不执行父类的。
最后是主函数,因为主函数一个程序只有一个,所以只执行一次本程序的主函数。
综上所述,java中子类继承父类程序各成员的执行顺序应该是:
父类的静态代码块—>子类的静态代码块—>主方法(执行哪个程序就执行哪个程序的主方法)—>父类的非静态代码块—>父类的无参构造函数—>子类的非静态代码块—>子类的无参构造函数(若实际子类执行的是有参构造函数,则不执行无参构造函数)—>成员函数(指定执行哪个就执行哪个成员函数,若重写了父类成员函数,则只执行子类的成员函数)。
程序运行时(一个类中),会第一时间加载运行静态代码块,一旦创建对象,就会执行非静态代码块以及无参构造方法。 而在继承中,程序运行时 会先加载父类中静态代码块 然后加载本身静态代码块,一旦创建对象(运用子类构造方法创建),就会调用 父类非静态代码块,父类构造方法,然后就是本身 非静态代码块,本身构造方法。