Java中类的成员之代码块


  

引言:

Java中类的成员除了常用的属性、方法、构造器以外,还有代码块和内部类。其中代码块主要是用来做一些初始化的工作。

  1. 代码块的作用:用来初始化类、对象

  2. 代码块如果有修饰的话,只能使用static.

  3. 分类:静态代码块 and 非静态代码块

  4. 静态代码块

    • 内部可以有输出语句
    • 随着类的加载而执行(注:静态方法随着类的加载而加载),而且只执行一次
    • 作用:初始化类的信息
    • 如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
    • 静态代码块的执行要优先于非静态代码块的执行
    • 静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构
  5. 非静态代码块

    • 内部可以有输出语句
    • 随着对象的创建而执行,且比构造器先执行
    • 每创建一个对象,就执行一次非静态代码块
    • 作用:可以在创建对象时,对对象的属性等进行初始化
    • 如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
    • 非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法

java类中的常用结构:

public class BlockTest {
	public static void main(String[] args) {

		String desc = Person.desc;
		System.out.println(desc);

		Person p1 = new Person();
		Person p2 = new Person();
		System.out.println(p1.age);

		Person.info();
	}
}

class Person{
	//非静态属性
	String name;
	int age;
    //静态属性
	static String desc = "我是一个人";

	//空参构造器
	public Person(){

	}
    //带参构造器
	public Person(String name,int age){
		this.name = name;
		this.age = age;
	}

	//非static的代码块
	{
		System.out.println("hello, block - 2");
	}
	{
		System.out.println("hello, block - 1");
		//调用非静态结构
		age = 1;
		eat();
		//调用静态结构
		desc = "我是一个爱学习的人1";
		info();
	}
	//static的代码块
	static{
		System.out.println("hello,static block-2");
	}
	static{
		System.out.println("hello,static block-1");
		//调用静态结构
		desc = "我是一个爱学习的人";
		info();
		//不可以调用非静态结构
//		eat();
//		name = "Tom";
	}

	//非静态方法
	public void eat(){
		System.out.println("吃饭");
	}
    //方法的重写(覆盖)
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
    //静态方法
	public static void info(){
		System.out.println("我是一个快乐的人!");
	}
}

由父及子,静态先行:

class Root{
    static{
        //step_1
        System.out.println("Root的静态初始化块");
    }
    {
        //step_4
        System.out.println("Root的普通初始化块");
    }
    public Root(){
        super();//默认调用父类空参构造器
        //step_5
        System.out.println("Root的无参数的构造器");
    }
}
class Mid extends Root{
    static{
        //step_2
        System.out.println("Mid的静态初始化块");
    }
    {
        //step_6
        System.out.println("Mid的普通初始化块");
    }
    public Mid(){
        super();//默认调用父类空参构造器
        //step_7
        System.out.println("Mid的无参数的构造器");
    }
    public Mid(String msg){
        this();//通过this调用同一类中重载的构造器
        //step_8
        System.out.println("Mid的带参数构造器,其参数值:" + msg);
    }
}
class Leaf extends Mid{
    static{
        //step_3
        System.out.println("Leaf的静态初始化块");
    }
    {
        //step_9
        System.out.println("Leaf的普通初始化块");
    }
    public Leaf(){
        super("大虫子,养虫子");//通过super调用父类中有一个字符串参数的构造器
        //step_10
        System.out.println("Leaf的构造器");
    }
}
public class LeafTest{
    public static void main(String[] args){
        new Leaf();
        System.out.println();
        new Leaf();
/*
		Root的静态初始化块
        Mid的静态初始化块
        Leaf的静态初始化块
        Root的普通初始化块
        Root的无参数的构造器
        Mid的普通初始化块
        Mid的无参数的构造器
        Mid的带参数构造器,其参数值:大虫子,养虫子
        Leaf的普通初始化块
        Leaf的构造器

        Root的普通初始化块
        Root的无参数的构造器
        Mid的普通初始化块
        Mid的无参数的构造器
        Mid的带参数构造器,其参数值:大虫子,养虫子
        Leaf的普通初始化块
        Leaf的构造器
*/
    }
}
class Father {
    static {
        System.out.println("11111111111");
    }
    {
        System.out.println("22222222222");
    }
    public Father() {
        System.out.println("33333333333");
    }

}

public class Son extends Father {
    static {
        System.out.println("44444444444");
    }
    {
        System.out.println("55555555555");
    }
    public Son() {
        System.out.println("66666666666");
    }
    //main方法既是程序入口,也是静态方法。由父及子 静态先行。main方法的执行也需要先有类的结构
    public static void main(String[] args) {
        System.out.println("77777777777");
        System.out.println("************************");
        new Son();
        System.out.println("************************");
        new Son();
        System.out.println("************************");
        new Father();
/*
        11111111111
        44444444444
        77777777777
        ************************
        22222222222
        33333333333
        55555555555
        66666666666
        ************************
        22222222222
        33333333333
        55555555555
        66666666666
        ************************
        22222222222
        33333333333
*/
    }
}

对属性的显示赋值和在代码块中赋值的先后执行顺序:

public class OrderTest {
    public static void main(String[] args) {
        Order1 o1 = new Order1();
        System.out.println(o1.orderId);//2

        Order2 o2 = new Order2();
        System.out.println(o2.orderId);//2
    }
}
class Order1 {
    int orderId = 1;
    {
        orderId = 2;
    }
}
class Order2 {
    {
        orderId = 1;
    }
    int orderId = 2;
}

文章作者: YangChongZhi
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 YangChongZhi !
评论
 上一篇
Java中的final关键字 Java中的final关键字
   引言: Java中的final关键字,final表示为最终的,通常用来修饰常量,不允许改变。 final:最终的 final可以用来修饰的结构: 类、方法、变量 final 用来修饰一个类: 此类不能被其他类所继承。比如:
2021-01-02
下一篇 
Java中的单例设计模式 Java中的单例设计模式
   引言: 单例设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。 单例设计模式(Singleton)概念:  所谓的单例设计模式,就是采取一定的方法保证在整个软件系统中,对某个类只能存在一个对象
2021-01-02
  目录