文章目录
1、先执行静态代码块
package com.htl.test;
public class Test {
static {
System.out.println("static执行");
}
public static void main(String[] args) {
System.out.println("main执行............");
}
}
2、类中定义静态成员变量对象,会先创建对象
package com.htl.test;
public class User {
public User() {
System.out.println("User类的无参构造执行");
}
}
package com.htl.test;
public class Test {
public static void main(String[] args) {
System.out.println("main执行............");
}
static User user = new User();
static {
System.out.println("static执行");
}
}
静态代码的执行一定先于 main 方法,静态代码块和静态成员变量的执行顺序是由代码位置决定的,谁写前面就先执行谁。
3、只有在创建Test对象的时候,才会执行非静态代码块和非静态成员变量。
package com.htl.test;
public class Test {
{
System.out.println("Code执行");
}
User user = new User();
public static void main(String[] args) {
System.out.println("main执行............");
}
}
package com.htl.test;
public class Test {
{
System.out.println("Code执行");
}
User user = new User();
public static void main(String[] args) {
Test test1 = new Test();
System.out.println("main执行............");
Test test2 = new Test();
}
}
创建多少个对象,就会执行多少次代码块,创建多少个成员变量。非静态代码块和非静态成员变量的执行顺序是由代码位置决定的,谁写前面谁先执行。
4、如果同时存在非静态代码块和静态代码块,以及非静态成员变量和静态成员变量,先执行静态的东西,并且只执行一次,再执行非静态的东西(创建对象),创建多少个对象就会执行多少次。
package com.htl.test;
public class Test {
{
System.out.println("Code执行");
}
User user = new User();
static User user1 = new User();
static {
System.out.println("static执行");
}
public static void main(String[] args) {
Test test1 = new Test();
System.out.println("main执行............");
Test test2 = new Test();
}
}
5、加入父子级情况
package com.htl.test1;
public class Stub {
public Stub(String str) {
System.out.println(str + "object created");
}
}
package com.htl.test1;
public class Father {
static Stub fatherStaticStub = new Stub("Father static object--");
static {
System.out.println("father static code execute");
}
Stub fatherStub = new Stub("Father object--");
{
System.out.println("father code execute");
}
Stub stu;
public Father() {
System.out.println("父类 构造器 执行");
stu = new Stub("Father constructor create object--");
}
public void sayHello(){
System.out.println("hello from 父类");
}
}
package com.htl.test1;
public class Son extends Father{
static Stub sonStaticStub = new Stub("Son static object--");
static {
System.out.println("son static code execute");
}
Stub sonStub = new Stub("Son object--");
{
System.out.println("son code execute");
}
Stub stub;
public Son() {
System.out.println("子类 构造器 执行");
stu = new Stub("Son constructor create object--");
}
public void sayHello(){
System.out.println("hello from 子类");
}
}
package com.htl.test1;
public class Test1 {
public static void main(String[] args) {
Son son = new Son();
son.sayHello();
((Father)son).sayHello();
}
}
开始分析:
1、首先会加载 Father,则 Father 中的静态代码块和静态成员变量会优先执行。
2、再加载 Son,则 Son 中的静态代码块和静态成员变量会优先执行。
3、类加载完成后,创建对象,先创建 Father 对象;创建对象之前,先创建对象的资源。
4、执行 Father 构造器,完成对象创建。
5、再创建 Son 对象;创建对象之前,先创建对象的资源。
6、执行 Son 构造器,完成对象创建。
7、执行 sayHello 方法。
尽管进行了强制类型转换,但实际上对象本身还是内存中的子对象,所以 hello 都是来自于 son。