代码块
介绍:代码化块又称初始化块,属于类中的成员[即 是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过{ }包围起来
但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不能通过对象或类显式调用,而是加载类时,或创建对象时隐式调用
基本语法
[修饰符]{
代码
};
注意
(1)修饰符可有可没有,要写的话只能写static
(2)代码块分两类,使用static修饰的叫静态代码块,没有static修饰的,叫普通代码块/非静态代码块
(3)逻辑语句可以为任何逻辑语句(输入、输出、方法调用、循环、判断等)
(4) ; 号可以写上,也可以省略
好处
1.相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作
2.场景:如果多个构造器中都有重复的语句,可以抽到初始化块中,提高代码的重用性
例:对比有无代码块的区别
package com.hspedu.Codeblock;
public class CodeBlock01 {
}
class Movie{
private String name;
private double price;
private String director;
//3个构造器 ->重载
//(1)下面的三个构造器都有相同的语句
//(2)这样代码看起来比较冗余
//(3)这时可以把相同的语句,放入一个代码块中
public Movie(String name) {
System.out.println("电影屏幕打开...");
System.out.println("广告开始...");
System.out.println("电影正式开始...");
this.name = name;
}
public Movie(String name, double price) {
System.out.println("电影屏幕打开...");
System.out.println("广告开始...");
System.out.println("电影正式开始...");
this.name = name;
this.price = price;
}
public Movie(String name, double price, String director) {
System.out.println("电影屏幕打开...");
System.out.println("广告开始...");
System.out.println("电影正式开始...");
this.name = name;
this.price = price;
this.director = director;
}
}
package com.hspedu.Codeblock;
public class CodeBlock01 {
public static void main(String[] args) {
Movie movie = new Movie("你好,李焕英");
System.out.println("===========");
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) {
this.name = name;
this.price = price;
this.director = director;
}
}
第二段代码的输出结果
使用细节
1.static代码块也叫静态代码块,作用是对类机械初始化,而且它随着类的加载而执行,并且只会执行一次(创建多次对象,只执行一次),如果是普通代码块,每创建一个对象,就执行一次
2.类什么时候被加载
(1)创建对象实例时(new)
(2)创建子类对象实例,父类也会被加载
(3)使用类的静态成员时(静态属性,静态方法)
package com.hspedu.Codeblock;
public class CodeBlockDetail01 {
public static void main(String[] args) {
//类被加载的情况举例
//1.创建子类对象
//AA aa = new AA();
//2.创建子类对象实例,父类也会被加载
//AA aa2 = new AA();
//3.使用类的静态成员时(静态属性,静态方法)
//System.out.println(Cat.n1);
//static代码块在创建多次对象时,只执行一次
//普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。
//DD dd = new DD();
//DD dd1 = new DD();
// 如果只是使用类的静态成员时,普通代码块并不会被执行
//普通代码块在new对象时被调用,与类加载无关
//可以这样简单理解:普通代码块时构造器的补充
System.out.println(DD.n1);
}
}
class DD{
public static int n1 = 8888;//静态属性
//静态代码块
static{
System.out.println("DD 的静态代码块被执行");
}
{
System.out.println("DD 的普通代码块被执行");
}
}
class Cat{
public static int n1 = 999;//静态书写
static{
System.out.println("Cat 对静态代码块被执行");
}
}
class BB{
//静态代码块
static{
System.out.println("BB 的静态代码块被执行");
}
}
class AA extends BB{
//静态代码块
static{
System.out.println("AA 的静态代码块被执行");
}
}
3.普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会调用一次。如果只是使用类的静态成员时,普通代码块并不会被执行
小结
(1)static代码块时类加载时执行,只会执行一次
(2)普通代码代码块是类加载时执行,只会执行一次
(3)记住类加载的3种情况
4.创建一个对象时,在类的调用顺序是:(重点,难点)
先静态,再普通,最后构造器,同级按定义顺序
package com.hspedu.Codeblock;
public class CodeBlockDetail02 {
public static void main(String[] args) {
A a = new A();
//输出结果(1)A 的静态代码块01(2)getN1被调用...(3)getN2被调用...(4)A 普通代码块01(5)A() 构造器被调用
}
}
class A{
private int n2 = getN2(); //普通属性的初始化
{//普通代码块
System.out.println("A 普通代码块01");
}
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() 构造器被调用");
}
}
5.构造方法(构造器)的最前面其实隐含了super()和调用普通代码块
package com.hspedu.Codeblock;
public class CodeBlockDetail03 {
public static void main(String[] args) {
new BBB();
}
}
class AAA{//父类Object
{
System.out.println("AAA的普通代码块");
}
public AAA(){
System.out.println("AAA() 构造器被调用....");
}
}
class BBB extends AAA{
{
System.out.println("BBB的普通代码块....");
}
public BBB() {
//(1)super()
//(2)调用本类的普通代码块
System.out.println("BBB() 构造器被调用....");
}
}
6.创建一个子类对象时(继承关系),调用顺序
(1)父类静态
(2)子类静态
(3)父类普通
(4)父类构造方法
(5)子类普通
(6)子类构造方法
7.静态代码块只能直接调用静态成员,普通代码块可以调用任意成员