第三章:代码块

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 一、代码块
  • 总结


前言

代码块是只有方法体的类成员。


一、代码块

代码块又成为初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。但与方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显性调用,而是加载类时,或创建对象时隐式调用。

//语法形式
修饰符
{
	代码
};

代码块语法细则
修饰符可有可无,要写的话也只能写static
;号可写可不写
代码块使用好处
相当于另外一种形式的构造器,可以做初始化的操做
如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性
先调用代码块的内容,在调用构造器
package com.hspedu.codeblock_;

public class CodeBlock01 {
	public static void main(String[] args) {
		Movie movie = new Movie("你好, 李焕英");
		System.out.println("===============");
		Movie movie2 = new Movie("唐探 3", 100, "陈思诚");
	}
} 

class Movie {
	private String name;
	private double price;
	private String director;
	//3 个构造器-》 重载
	//老韩解读
	//(1) 下面的三个构造器都有相同的语句
	//(2) 这样代码看起来比较冗余
	//(3) 这时我们可以把相同的语句, 放入到一个代码块中, 即可
	//(4) 这样当我们不管调用哪个构造器, 创建对象, 都会先调用代码块的内容
	//(5) 代码块调用的顺序优先于构造器..
	{
		System.out.println("电影屏幕打开...");
		System.out.println("广告开始...");
		System.out.println("电影正是开始...");
	};
	
	public Movie(String name) {
		System.out.println("Movie(String name) 被调用...");
		this.name = name;
	}
	
	public Movie(String name, double price) {
		this.name = name;
		this.price = price;
	} 
	
	public Movie(String name, double price, String director) {
		System.out.println("Movie(String name, double price, String director) 被调用...");
		this.name = name;
		this.price = price;
		this.director = director;
	}
}
代码块使用细则
static代码块也叫静态代码块,是随着类的加载而执行,并且只会执行一次;普通代码块,每创建一次对象,就执行。使用静态成员或创建多个对象都只会加载一次类
普通的代码块,在创建对象时,会被隐式的调用。被创建一次,就会调用一次。如果只是使用类的静态成员时,普通代码块并不会执行,可以简单理解,普通代码块时构造器的补充
类什么时候被加载
创建对象实例时(new)
创建子类对象实例,父类也会被加载
使用类的静态成员时(静态属性,静态方法)
使用类的静态成员时,父类也会被加载
构造器的最前面其实隐含了super()和调用普通代码块,静态代码块。属性初始化,在类加载时,就执行完毕了
静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员
创建一个对象时,在一个类调用顺序
1. 调用静态代码块和静态属性初始化,多个则按定义顺序
2. 调用普通代码块和普通属性的初始化,多个则按定义顺序
3. 调用构造方法,定义了另一种方法
package com.hspedu.codeblock_;

public class CodeBlockDetail02 {
	public static void main(String[] args) {
		A a = new A();
		// (1) A 静态代码块 01 
		// (2) getN1 被调用...
		// (3) A 普通代码块 01
		// (4) getN2 被调用..
		// (5)A() 构造器被调用
	}
} 

class A {
	{ //普通代码块
		System.out.println("A 普通代码块 01");
	} 
	
	private int n2 = getN2();//普通属性的初始化
	
	static { //静态代码块
		System.out.println("A 静态代码块 01");
	} 
	
	private static int n1 = getN1();//静态属性的初始化
	
	public static int getN1() {
		System.out.println("getN1 被调用...");
		return 100;
	}
	
	public int getN2() { //普通方法/非静态方法
		System.out.println("getN2 被调用...");
		return 200;
	} 
	//无参构造器
	public A() {
		System.out.println("A() 构造器被调用");
	}
}

在继承关系中创建一个对象,在一个类的调用顺序
1. 父类的静态代码块和静态属性(优先级一样按定义顺序执行)
2. 子类的静态代码块和静态属性(优先级一样按定义顺序执行)
3. 父类的普通代码块和普通属性初始化(优先级一样按定义顺序执行)
4. 父类的构造方法
5. 子类的普通代码块和普通属性初始化(优先级一样按定义顺序执行)
6. 子类的构造方法
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
	}
}


总结

对象的创建有着严格的代码执行顺序。

你可能感兴趣的:(#,Java面向对象编程高级知识,java,jvm)