初次学习代码块、构造代码块、静态代码块后,决定写此文章特别总结一下学习成果,本文用最浅显的语言讲述代码块,若有错误请大神们指出,十分感谢(鞠躬)
1.普通代码块
存在于方法中,用{}括起来
这种代码块称为普通代码块,与平时语句执行无异,顺序执行即可
public class A{
public static void main(String[] args){
{
System.out.println("我是第一个普通代码块");
}
System.out.println("普通代码块和普通语句没区别");
{
System.out.println("我是第二个普通代码块");
}
}
}
/*
运行结果:
我是第一个普通代码块
普通代码块和普通语句没区别
我是第二个普通代码块
*/
2.构造代码块
存在于类体中,用{}括起来
每次创建对象时都会调用,且构造代码块先于构造方法执行,注意!若构造代码块在main方法所在类中, main方法没有对本类new对象,构造代码块不会执行,因为此时对象还没创建,main方法之所以能调用是因为static关键字的缘故,即使没有new对象,jvm也可以通过类名调用!(具体可查阅main方法为什么用public static void修饰)
具体区别请看如下代码
此时 main方法中有语句new B2();
public class B2{
public static void main(String[] args){
System.out.println("main方法被执行");
new B();
}
public B2(){
System.out.println("构造方法被执行");
}
{
System.out.println("构造代码块被执行");
}
}
/*
运行结果:
main方法被执行
构造代码块被执行
构造方法被执行
*/
下面我们将语句new B2删去
public class B2{
public static void main(String[] args){
System.out.println("main方法被执行");
//new B2();
}
public B2(){
System.out.println("构造方法被执行");
}
{
System.out.println("构造代码块被执行");
}
}
/*
运行结果:
main方法被执行
*/
输出结果仅有“main方法被执行”
由此可见,若需要在main方法所在类执行构造代码块,需要在main方法中new main方法所在类的对象
3.静态代码块
存在于方法之中,并被static修饰,及{}括起来
形如static{
}
静态代码块随着类的加载而执行,因此静态代码块只执行一次(class文件只加载一次),当编译完毕后,通过jvm解释class文件时,main方法所在类首先被加载进方法区,并查看有无父类.
若有 则 (1)父类静态变量进行默认初始化 如若类体中有语句static int a = 1; 则默认初始化a为0
(2)父类静态变量进行显示初始化 如若类体中有语句static int a = 1; 则显示初始化a为1
(3)执行父类静态代码块
(4)子类静态变量进行默认初始化
(5)子类静态变量进行显示初始化
(6)执行子类静态代码块
(7)执行子类的main方法(假设此时main方法有对本类new对象 另:若没有则在此步骤截止)
(8)父类非静态变量进行默认初始化
(9)父类非静态变量进行显示初始化
(10)执行父类构造代码块
(11)执行父类的构造方法
(12)子类的非静态变量进行默认初始化
(13)子类的非静态变量进行显示初始化
(14)执行子类的构造代码块
(15)执行子类的构造方法
具体代码如下所示
class B{
static int a = 1;
int a2 = 2;
static
{
System.out.println("父类static变量"+a);
System.out.println("父类静态代码块");
}
public B(){
System.out.println("父类构造方法被执行");
}
{
System.out.println("父类非static变量"+a2);
System.out.println("父类构造代码块");
}
}
class A extends B{
static int b = 3;
int b2 = 4;
static
{
System.out.println("子类static变量"+b);
System.out.println("子类静态代码块");
}
public static void main(String[] args){
System.out.println("main方法被执行");
new A();
}
public A(){
System.out.println("子类构造方法被执行");
}
{
System.out.println("子类非static变量"+b2);
System.out.println("子类构造代码块");
}
}
/*
运行结果:
父类static变量1
父类静态代码块
子类static变量3
子类静态代码块
main方法被执行
父类非static变量2
父类构造代码块
父类构造方法被执行
子类非static变量4
子类构造代码块
子类构造方法被执行
*/
若main方法所在类没有父类,则按规律执行即可
由此,我们还可以总结出类的加载规律: (1)先父类后子类
(2)先静态后非静态
(3)先属性后方法
(4)先声明后赋值
至此 总结完毕
第一篇博客,请大神们多多指教,指点一二,再次感谢