1.类中代码的执行顺序
1,先执行静态代码块
public class Test {
static {
System.out.println("static code execute");
}
public static void main(String[] args) {
System.out.println("main() execute");
}
}
// static code execute
// main() execute
2,类中定义静态成员变量对象,会先创建对象
static {
System.out.println("static code execute");
}
static User user = new User();
public static void main(String[] args) {
System.out.println("main() execute");
}
// static code execute
// User init
// main() execute
static User user = new User();
static {
System.out.println("static code execute");
}
public static void main(String[] args) {
System.out.println("main() execute");
}
// User init
// static code execute
// main() execute
静态代码的执行一定先于main方法,静态代码块和静态成员变量的执行顺序是由代码位置决定的,谁写前面就先执行谁
{
System.out.println("code execute");
}
User user = new User();
public static void main(String[] args) {
System.out.println("main() execute");
}
// main() execute
// 如果是非静态代码块和成员变量,不执行
3,只有在创建Test对象的时候,才会执行非静态代码块和非静态成员变量。
{
System.out.println("code execute");
}
User user = new User();
public static void main(String[] args) {
System.out.println("main() execute");
Main main = new Main();
}
// main() execute
// code execute
// User init
{
System.out.println("code execute");
}
User user = new User();
public static void main(String[] args) {
Main main = new Main();
System.out.println("main() execute");
}
// code execute
// User init
// main() execute
{
System.out.println("code execute");
}
User user = new User();
public static void main(String[] args) {
System.out.println("main() execute");
Main main = new Main();
Main main1 = new Main();
Main main2 = new Main();
}
/*
main() execute
code execute
User init
code execute
User init
code execute
User init
*/
创建多少个对象,就会执行多少次代码块,创建多少个成员变量,非静态代码块和非静态成员变量的执行顺序是由代码位置决定的,谁写前面谁先执行
4,如果同时存在非静态代码块和静态代码块,以及非静态成员变量和静态成员变量,先执行静态的东西,并且只执行一次,再执行非静态的东西(要创建对象),创建多少个对象就会执行多少次
User user = new User();
{
System.out.println("code execute");
}
static User user1 = new User();
static {
System.out.println("static code execute");
}
public static void main(String[] args) {
System.out.println("main() execute");
Main main = new Main();
Main main1 = new Main();
Main main2 = new Main();
}
/*
User init
static code execute
main() execute
User init
code execute
User init
code execute
User init
code execute
*/
// 静态属于类的,非静态属于对象的
5,加入父子类
public class Stub {
public Stub(String str){
System.out.println(str + "obj created");
}
}
public class Parent {
static Stub parentStaticStub = new Stub("parent static obj");
static {
System.out.println("parent static code execute");
}
{
System.out.println("parent code execute");
}
Stub parentStub = new Stub("parent obj");
Stub stub;
public Parent(){
System.out.println("parent constructor exec");
stub = new Stub("parent constructor create obj");
}
public void sayHi(){
System.out.println("hi from parent");
}
}
public class Child extends Parent{
static Stub childStaticStub = new Stub("child static obj");
static {
System.out.println("child static code execute");
}
{
System.out.println("child code execute");
}
Stub childStub = new Stub("child obj");
Stub stub;
public Child(){
System.out.println("child constructor exec");
stub = new Stub("child constructor create obj");
}
public void sayHi(){
System.out.println("hi from child");
}
}
public class Test {
public static void main(String[] args) {
Child child = new Child();
child.sayHi();
((Parent)child).sayHi();
}
}
/*
parent static objobj created
parent static code execute
child static objobj created
child static code execute
parent code execute
parent objobj created
parent constructor exec
parent constructor create objobj created
child code execute
child objobj created
child constructor exec
child constructor create objobj created
hi from child
hi from child
*/
开始分析
1,首先会加载Parent,则Parent中的静态代码块和静态成员变量会优先执行。(子类构造器第一行默认有个super())
parent static objobj created
parent static code execute
2.加载Child,Child中的静态代码块和静态成员变量会优先执行(先加载类,再执行)
child static objobj created
child static code execute
3.类加载完成之后,创建对象,先创建Parent对象,创建对象之前先创建对象的资源。
parent code execute
parent objobj created
4.执行Parent构造器,完成对象创建
parent constructor exec
parent constructor create objobj created
5.创建Child对象之前,先创建对象的资源
child code execute
child objobj created
6.执行Child构造器,完成对象创建
child constructor exec
child constructor create objobj created
7.执行sayHi方法
hi from child
hi from child
尽管进行了强制类型转换,但实际上对象本身还是内存中的子对象,所以hi都是来自于child
父类静态字段=父类静态代码块(顺序加载)->子类静态字段=子类静态代码块(顺序加载)->父类成员变量和非静态块(顺序加载)->父类构造函数->子类成员变量和非静态块(顺序加载)->子类构造函数