java代码块

java代码块

基本介绍

代码化块又称为初始化块,属于类中的成员(即,是类的一部分),类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。

没有方法名,没有返回值,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用

基本语法

[修饰符]{

代码}

注意:

  1. 修饰符可选,要写只能写static
  2. 代码块分为两类,使用static修饰的叫静态代码块,没有static修饰的叫普通代码块
  3. 逻辑语句可以写任意逻辑语句

代码块的好处和案例演示

  1. 相当于另一种形式的构造器(对构造器的补充机制),可以做初始化的操作

  2. 场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性

  3. 代码块的快速入门: CodeBlock01.java

    class CodeBlock{
    	public static void main(String[] args) {
            move move = new move("y");
            System.out.println("=========");
            move move1 = new move("x",100);
            System.out.println("=========");
            move move2=new move("z",100,"c");
        }
    }
    class move{
        private String name;
        private double price;
        private String director;
        /*public move(String name) {
            System.out.println("电影屏幕打开....");
            System.out.println("电影广告...");
            System.out.println("电影开始播放...");
            System.out.println("调用move(String name)");
        }
        public move(String name, double price) {
            System.out.println("电影屏幕打开....");
            System.out.println("电影广告...");
            System.out.println("电影开始播放...");
            System.out.println("调用move(String name, double price)");
        }
        public move(String name, double price, String director) {
            System.out.println("电影屏幕打开....");
            System.out.println("电影广告...");
            System.out.println("电影开始播放...");
            System.out.println("调用move(String name, double price, String director)");
        }*/
        /**
         * 可以把相同的语句放到一个代码块中
         * 这样当我们不管调用那个构造器,创建对象,都会先调用代码块的内容
         * 代码块调用的顺序优先于构造器
         */
        {
            System.out.println("电影屏幕打开....");
            System.out.println("电影广告...");
            System.out.println("电影开始播放...");
        }
        public move(String name) {
            System.out.println("调用move(String name)");
        }
        public move(String name, double price) {
            System.out.println("调用move(String name, double price)");
        }
        public move(String name, double price, String director) {
            System.out.println("调用move(String name, double price, String director)");
        }
    }
    

    输出:

    电影屏幕打开....
    电影广告...
    电影开始播放...
    调用move(String name)
    =========
    电影屏幕打开....
    电影广告...
    电影开始播放...
    调用move(String name, double price)
    =========
    电影屏幕打开....
    电影广告...
    电影开始播放...
    调用move(String name, double price, String director)
    
    进程已结束,退出代码为 0
    

代码块使用注意事项和细节讨论

一.static代码块

static代码块也叫做静态代码块,作用就是对类进行初始化,而且它随着类加载而加载,并且只执行一次,如果是普通代码块,每创建一个对象,就执行一次。

二.类什么时候被加载
  1. 创建对象实例时(new)

    public class CodeBlockDetail01 {
        public static void main(String[] args) {
        //创建对象实例时(new)
            AA aa = new AA();
        }
    }
    class AA{
        //静态代码块
        static{
            System.out.println("AA的静态代码块");
        }
    }
    
    AA的静态代码块
    
  2. 创建子类对象实例,父类也会被加载

    public class CodeBlockDetail01 {
        public static void main(String[] args) {
        //创建对象实例时(new)
    //        AA aa = new AA();
            //创建子类对象实例,父类也会被加载
            AA aa1 = new AA();
            
        }
    }
    class BB{
        //静态代码块
        static{
            System.out.println("BB的静态代码块");
        }
    }
    
    class AA extends BB{
        //静态代码块
        static{
            System.out.println("AA的静态代码块");
        }
    }
    
    BB的静态代码块
    AA的静态代码块
    
  3. 使用类的静态成员时

    public class CodeBlockDetail01 {
        public static void main(String[] args) {
        //创建对象实例时(new)
    //        AA aa = new AA();
            //创建子类对象实例,父类也会被加载
    //        AA aa1 = new AA();
            //使用类的静态成员时
            System.out.println(Cat.n1);
        }
    }
    class Cat{
        public static int n1=999;//静态属性
        //静态代码块
        static{
            System.out.println("BB的静态代码块");
        }
    }
    
    Cat的静态代码块
    999
    
    public class CodeBlockDetail01 {
        public static void main(String[] args) {
        //创建对象实例时(new)
    //        AA aa = new AA();
            //创建子类对象实例,父类也会被加载
    //        AA aa1 = new AA();
            //使用类的静态成员时
            System.out.println(Cat.n1);
        }
    }
    class Animal{
        //静态代码块
        static{
            System.out.println("Animal的静态代码块");
        }
    }
    class Cat extends Animal{
        public static int n1=999;//静态属性
        //静态代码块
        static{
            System.out.println("Cat的静态代码块");
        }
    }
    
    Animal的静态代码块
    Cat的静态代码块
    999
    
三.普通代码块

普通代码块,在创建对象实例时,会内隐式的调用。

被创建一次,就会调用一次

如果只是使用类的静态成员时,普通代码块并不会被执行

public class CodeBlockDetail01 {
    public static void main(String[] args) {
    //创建对象实例时(new)
//        AA aa = new AA();
        //创建子类对象实例,父类也会被加载
//        AA aa1 = new AA();
        //使用类的静态成员时
//        System.out.println(Cat.n1);
        //static代码块也叫做静态代码块,作用就是对类进行初始化,而且它随着类加载而加载,并且只执行一次
        //代码System.out.println("DD的静态代码块");会执行几次?
        DD dd = new DD();
        DD dd1 = new DD();
        

    }
}
class DD{
    //静态代码块
    static{
        System.out.println("DD的静态代码块");
    }
}
DD的静态代码块
public class CodeBlockDetail01 {
    public static void main(String[] args) {
    //创建对象实例时(new)
//        AA aa = new AA();
        //创建子类对象实例,父类也会被加载
//        AA aa1 = new AA();
        //使用类的静态成员时
//        System.out.println(Cat.n1);
        //static代码块也叫做静态代码块,作用就是对类进行初始化,而且它随着类加载而加载,并且只执行一次
        //代码System.out.println("DD的静态代码块");会执行几次?
//        DD dd = new DD();
//        DD dd1 = new DD();
        //普通的代码块,在创建对象实例时,会被隐式的调用
        //被创建一次,就会调用一次
        //如果只是使用类的静态成员时,普通代码块并不会执行
        System.out.println(DD.n);


    }
}
class DD{
    public static int n=999;
    //静态代码块
    static{
        System.out.println("DD的静态代码块");
    }
    //普通代码块
    {
        System.out.println("DD的普通代码块");
    }
}
DD的静态代码块
999
四.调用顺序

1.调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们的顺序调用)

public class CodeBlockDetail02 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
    }
}
class A{
    //静态属性的初始化
    private static int n1=getN1();
    //静态代码块
    static{
        System.out.println("A 静态代码块");
    }
    public static int getN1(){
        System.out.println("getN1被调用");
        return 100;
    }
}
class B{
    //静态代码块
    static{
        System.out.println("B 静态代码块");
    }
    //静态属性的初始化
    private static int n1=getN1();

    public static int getN1(){
        System.out.println("getN1被调用");
        return 100;
    }
}
getN1被调用
A 静态代码块
B 静态代码块
getN1被调用

2.调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化的优先级一样,如果有多个普通代码块和多个普通变量初始化,则按他们的顺序调用)

public class CodeBlockDetail02 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
    }
}
class A{
    //普通属性的初始化
    private int n2=getN2();
    //普通代码块
    {
        System.out.println("A 普通代码块");
    }
    //静态属性的初始化
    private static int n1=getN1();
    //静态代码块
    static{
        System.out.println("A 静态代码块");
    }
    public static int getN1(){
        System.out.println("getN1被调用");
        return 100;
    }
    public static int getN2(){
        System.out.println("getN2被调用");
        return 200;
    }
}
class B{
    //普通代码块
    {
        System.out.println("B 普通代码块");
    }
    //普通属性的初始化
    private int n2=getN2();

    //静态代码块
    static{
        System.out.println("B 静态代码块");
    }
    //静态属性的初始化
    private static int n1=getN1();

    public static int getN1(){
        System.out.println("getN1被调用");
        return 100;
    }
    public static int getN2(){
        System.out.println("getN2被调用");
        return 200;
    }
}
getN1被调用
A 静态代码块
getN2被调用
A 普通代码块
B 静态代码块
getN1被调用
B 普通代码块
getN2被调用

3.调用构造方法

package CodeBlock.Block01;

public class CodeBlockDetail02 {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
    }
}
class A{
    //普通属性的初始化
    private int n2=getN2();
    //普通代码块
    {
        System.out.println("A 普通代码块");
    }
    //静态属性的初始化
    private static int n1=getN1();
    //静态代码块
    static{
        System.out.println("A 静态代码块");
    }
    public static int getN1(){
        System.out.println("getN1被调用");
        return 100;
    }
    public static int getN2(){
        System.out.println("getN2被调用");
        return 200;
    }

    public A() {
        System.out.println("A的构造器");
    }
}
class B{
    public B() {
        System.out.println("B的构造器");
    }
    //普通代码块
    {
        System.out.println("B 普通代码块");
    }
    //普通属性的初始化
    private int n2=getN2();

    //静态代码块
    static{
        System.out.println("B 静态代码块");
    }
    //静态属性的初始化
    private static int n1=getN1();

    public static int getN1(){
        System.out.println("getN1被调用");
        return 100;
    }
    public static int getN2(){
        System.out.println("getN2被调用");
        return 200;
    }


}
getN1被调用
A 静态代码块
getN2被调用
A 普通代码块
A的构造器
B 静态代码块
getN1被调用
B 普通代码块
getN2被调用
B的构造器
五.构造器

构造器的最前面其实隐含了 super()和 调用普通代码块,静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此优先于构造器和普通代码块执行的

六.

我们看一下创建一个子类对象时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:

1.父类的静态代码块和静态属性(优先级一样,按定义顺序执行)

2.子类的静态代码块和静态属性(优先级一样,按定义顺序执行)

3.父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

4.父类的构造方法

5.子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

6.子类的构造方法/面试题

七.

7)静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。

public class CodeBlockDetail04 {
	public static void main(String[] args) {
	//老师说明
	//(1) 进行类的加载
	//1.1 先加载 父类 A02 1.2 再加载 B02
	//(2) 创建对象
	//2.1 从子类的构造器开始
	//new B02();//对象
	new C02();
	}
}
class A02 { //父类
	private static int n1 = getVal01();
	static {
		System.out.println("A02 的一个静态代码块..");//(2)
	}
	{
		System.out.println("A02 的第一个普通代码块..");//(5)
	}
	public int n3 = getVal02();//普通属性的初始化
	public static int getVal01() {
		System.out.println("getVal01");//(1)
		return 10;
	}
	public int getVal02() {
		System.out.println("getVal02");//(6)
		return 10;
	}
	public A02() {//构造器
	//隐藏
	//super()
	//普通代码和普通属性的初始化...... System.out.println("A02 		的构造器");//(7)
	}
}
class C02 {
	private int n1 = 100;
	private static int n2 = 200;
	private void m1() {
	}
	private static void m2() {
	}
    
	static {
		//静态代码块,只能调用静态成员
		//System.out.println(n1);错误
		System.out.println(n2);//ok
		//m1();//错误
		m2();
	}
    
	{
		//普通代码块,可以使用任意成员
		System.out.println(n1);
		System.out.println(n2);//ok
		m1();
		m2();
	}
    
}
class B02 extends A02 { //
	private static int n3 = getVal03();
    
	static {
		System.out.println("B02 的一个静态代码块..");//(4)
	}
    
	public int n5 = getVal04();
    
	{
		System.out.println("B02 的第一个普通代码块..");//(9)
	}
    
	public static int getVal03() {
		System.out.println("getVal03");//(3)
		return 10;
	}
	public int getVal04() {
		System.out.println("getVal04");//(8)
		return 10;
	}
	//一定要慢慢的去品.. 
    public B02() {//构造器
		//隐藏了
		//super()
		//普通代码块和普通属性的初始化... 							System.out.println("B02 	的构造器");//(10)
		// TODO Auto-generated constructor stub
	}
}
posted @ 2021-10-17 15:13  Anesthesi  阅读(55)  评论(0)    收藏  举报