代码块分为普通代码块,构造块,静态代码块和同步代码块,但是这里只先介绍前三个代码块,同步代码块先不做介绍。
1.普通代码块:定义在方法中的代码块,变量的作用域不同,为了防止变量重名;
public class Test{
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ; System.out.println("x = " +x);
}
int x = 100 ;
System.out.println("x = " +x);
}
}
2.构造块【也叫实例代码块】:定义在类中的代码块,(不加任何修饰符)
class Person{
{ //定义在类中,不加任何修饰符,构造块
System.out.println("1.Person类的构造块");
}
public Person(){
System.out.println("2.Person类的构造方法");
}
}
public class Test{
public static void main(String[] args) {
new Person();
new Person();
}
}
构造块优先于构造方法执行,每产生一个新的对象就调用一次构造块,构造块可以进行简单的逻辑操作(在调用构造方法前)
3.静态代码块: 有static修饰代码块 ,且只输出一次 ;
a.非主类的静态代码块:
class Person{
{ //定义在类中,不加任何修饰符,构造块
System.out.println("1.Person类的构造块");
}
public Person(){
System.out.println("2.Person类的构造方法");
}
static { //定义在非主类中的静态块
System.out.println("3.Person类的静态块");
}
}
public class Test{
public static void main(String[] args) {
System.out.println("--start--");
new Person();
new Person();
System.out.println("--end--");
}
}
若是主方法中包含 静态代码块的类没有被加载或者调用 , 则静态代码块不输出;
若是主类继承了这个类,则静态代码块会优先main();(因为子类一定会调用 父类的构造方法,所以会有非主类的加载 )
若是主类没有继承这个类,则会在main()之后,但是实例化对象之前调用;
b. 主类中的静态代码块:
public class Test{
{
System.out.println("1.Test的构造块");
}public Test(){
System.out.println("2.Test的构造方法");
}static{ System.out.println("3.Test的静态块"); }
public static void main(String[] args) {
System.out.println("--start--");
new Test();
new Test();
System.out.println("--end--");
}
}
主类中的静态代码块一定会被调用,尽管没有创建主类的对象,且优先main()输出;
若是这个主类继承了父类,还是在父类静态代码块之后调用;
4.同步代码块:…
5.小总结:
若是创建一个子类的对象则实现顺序是:
父类的static
子类的static
父类的构造块
父类的构造函数
子类的构造块
子类的构造函数
注:不管是父类的静态代码块该是子类的静态代码块都只执行一次,但是构造块和构造函数是根据实例出来的对象个数决定的;
6.一道阿里的java校招笔试题
public class HelloA {
//构造方法
public HelloA(){
System.out.println("Hello A!父类构造方法");
}
//非静态代码块
{
System.out.println("i'm A class.父类非静态代码块");
}
//静态代码块
static{
System.out.println("static A 父类静态代码块");
}
}
public class HelloB extends HelloA {
//构造方法
public HelloB(){
System.out.println("Hello B! 构造方法");
}
//非静态代码块
{
System.out.println("i'm B class.非静态代码块");
}
//静态代码块
static{
System.out.println("static B 静态代码块");
}
public static void main(String[] args) {
System.out.println("---start---");
new HelloB();
new HelloB();
System.out.println("---end---");
}
}
上述代码的输出应该为:`
static A 父类静态代码块
static B 静态代码块 // 静态代码块都只执行一次,因为HelloB为主类,所以静态代码块优先于
main()输出;
---start---
i'm A class.父类非静态代码块
Hello A!父类构造方法 //父类的构造块和构造函数优先于子类的构造块和构造函数输出
i'm B class.非静态代码块
Hello B! 构造方法
i'm A class.父类非静态代码块 //构造块和构造函数的个数等于实例化对象的个数
Hello A!父类构造方法
i'm B class.非静态代码块
Hello B! 构造方法
---end---