java的学习:代码块

一、代码块的作用

在java,对于数据域的初始化除了通过构造器,以及声明时赋值,还有就是使用代码块进行初始化赋值

二、代码块的分类

代码块分为两种,一种是被static关键字修饰的静态代码块,一种是非静态代码块

class Person{
    ...
    //非静态代码块
    {
        System.out.println("这是非静态代码块");
    }

	 //静态代码块
    static {
        System.out.println("这是静态代码块");
    }
    ...
}

在例子中,Person中直接以{ }括起来的没有任何修饰的就是非静态代码块。而以static关键字修饰的static{ }就是静态代码块

2.1 非静态代码块

public class PersonTest {
    public static void main(String[] args) {
        Person p=new Person("张三");
        System.out.println(p);
        System.out.println("==============");
        Person p2=new Person("李四");
        System.out.println(p2);
    }
}

class Person{
    private String name;
    private int age;
    private static String gender="未知";

    public Person(String name) {
        this.name = name;
    }

    //非静态代码块
    {
        age=10;
        System.out.println("这是非静态代码块1");
    }

    //非静态代码块
    {
        System.out.println("这是非静态代码块2");
        //调用静态属性
        gender="男";
        //执行非静态方法
        walk();
        //执行静态方法
        desc();
    }

    public void walk(){
        System.out.println("这是非静态方法");
    }

    public static void desc(){
        System.out.println("这是静态方法");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

运行结果:
在这里插入图片描述
通过上面的例子发现非静态代码块:
作用:

  • 可以在创建对象时,对对象的属性进行初始化

特点:

  • 随着对象的创建而执行
  • 每创建一次对象时就执行一次非静态代码块。
  • 如果类中定义了多个代码块,就按照类声明中定义的次序来
  • 非静态代码块内部可以有输出语句

注意点:

  • 非静态代码块内部可以调用静态属性,非静态属性,静态方法,非静态方法。

2.2 静态代码块

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

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

class Person{
    private String name;
    private int age;
    private static String gender="未知";
    static String desc="这是个人";

    public Person(String name) {
        this.name = name;
    }

    static{
        System.out.println("这是静态代码块1");
        //调用静态方法
        desc();
        //调用非静态方法
        //walk();//Non-static method 'walk()'cannot be referenced from a static context
    }

    static{
        System.out.println("这是静态代码块2");
        //给静态属性赋值
        gender="男";
        desc="这是个男人";
        //给非静态属性赋值
        //age=10;//Non-static field 'age'cannot be referenced from a static context
    }

    public void walk(){
        System.out.println("这是非静态方法");
    }

    public static void desc(){
        System.out.println("这是静态方法");
    }
    
}

运行结果:
在这里插入图片描述

通过运行结果分析可以发现,在第一个分割符上方,是在通过类名.静态属性时(Person.desc)打印出来的,此时类就会加载到内存中,所以会执行静态代码块中的代码。而在运行结果的第二个分割符下的结果,是执行Person.desc()这个语句所打印出来的,因为类此时已经加载过了,一个类只会加载一次,所以这时没有再执行静态代码块。

静态代码块:
作用:

  • 可以对静态属性进行初始化

特点:

  • 随着类的加载而加载,并且只执行一次
  • 如果定义了多个静态代码块,按照顺序依次执行
  • 静态代码块在非静态代码块之前执行
  • 内部可以执行输出语句

注意点:

  • 静态代码块只能调用静态结构,不能调用非静态结构

三、各种属性赋值的先后顺序

例如:

public class PersonTest {

    public static void main(String[] args) {

        Person p=new Person("张三");
    }
}

class Person{

    //非静态代码块
    {
        System.out.println(this.id);
        System.out.println("这是非静态代码块1");
    }

    //静态代码块1
    static{
        System.out.println(Person.desc);
        desc="这是个人";
        System.out.println("这是静态代码块1");
    }

    private int id=getValue();
    private String name;
    private int age;

    private static String gender;
    private static String desc=getDesc();

    //静态代码块
    static{
        System.out.println("这是静态代码块2");
    }


    public Person() {
        System.out.println("这是无参构造");
    }

    public Person(String name) {
        //调用无参构造
        this();
        System.out.println("这是有一个参数的构造");
        this.name = name;
    }

    //非静态代码块
    {
        System.out.println("这是非静态代码块2");
    }

    private int getValue() {
        System.out.println("这是非静态属性(实例域)显式初始化");
        return 1;
    }

    private static String getDesc(){
        System.out.println("这是静态属性显式初始化");
        return "两个眼睛,一张嘴,两条腿";
    }



}

运行结果:
在这里插入图片描述
通过运行结果和代码的分析不难发现:

  1. 静态属性被初始化为默认值
  2. 静态属性的显式初始化和静态代码块的执行顺序,是按照类中定义的顺序依次执行
  3. 非静态属性被初始化为默认值
  4. 非静态属性的显式初始化和非静态代码块的执行顺序,是按照在类中声明的次序依次执行
  5. 构造器(如果构造器中第一行调用了其他构造器,则执行调用的构造器。如例子中一个参数的构造器,第一行通过this()调用了无参构造,则先执行无参构造,最后在执行一个参数的构造主体。)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章