代码块

如果成员变量想要初始化的值不是一个硬编码的常量值,而是需要通过复杂的计算或读取文件、或读取运行环境信息等方式才能获取的一些值,该怎么办呢?此时,可以考虑代码块(或初始化块)。

  • 代码块(或初始化块)的作用

  • 对Java类或对象进行初始化

  • 代码块(或初始化块)的分类

    • 一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块(static block)

    • 没有使用static修饰的,为非静态代码块。

1. 静态代码块

如果想要为静态变量初始化,可以直接在静态变量的声明后面直接赋值,也可以使用静态代码块。

1.1 语法格式

在代码块的前面加static,就是静态代码块。

【修饰符】 class 类{  
    static{  
        静态代码块  
    }  
}

1.2 静态代码块的特点

  1. 可以有输出语句。

  2. 可以对类的属性、类的声明进行初始化操作。

  3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。

  4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。

  5. 静态代码块的执行要先于非静态代码块。

  6. 静态代码块随着类的加载而加载,且只执行一次。

package com.atguigu.keyword;  
​  
public class Chinese {  
//    private static String country = "中国";  
​  
    private static String country;  
    private String name;  
​  
    {  
        System.out.println("非静态代码块,country = " + country);  
    }  
​  
    static {  
        country = "中国";  
        System.out.println("静态代码块");  
    }  
​  
    public Chinese(String name) {  
        this.name = name;  
    }  
}

package com.atguigu.keyword;  
​  
public class TestStaticBlock {  
    public static void main(String[] args) {  
        Chinese c1 = new Chinese("张三");  
        Chinese c2 = new Chinese("李四");  
    }  
}  

2. 非静态代码块

2.1 语法格式

【修饰符】 class 类{  
    {  
        非静态代码块  
    }  
    【修饰符】 构造器名(){  
        // 实例初始化代码  
    }  
    【修饰符】 构造器名(参数列表){  
        // 实例初始化代码  
    }  
}

2.2 非静态代码块的作用

和构造器一样,也是用于实例变量的初始化等操作。

2.3 非静态代码块的意义

如果多个重载的构造器有公共代码,并且这些代码都是先于构造器其他代码执行的,那么可以将这部分代码抽取到非静态代码块中,减少冗余代码。

2.4 非静态代码块的执行特点

  1. 可以有输出语句。

  2. 可以对类的属性、类的声明进行初始化操作。

  3. 除了调用非静态的结构外,还可以调用静态的变量或方法。

  4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。

  5. 每次创建对象的时候,都会执行一次。且先于构造器执行。

3. 举例

举例1:

(1)声明User类,

  • 包含属性:username(String类型),password(String类型),registrationTime(long类型),私有化

  • 包含get/set方法,其中registrationTime没有set方法

  • 包含无参构造,

    • 输出“新用户注册”,

    • registrationTime赋值为当前系统时间,

    • username就默认为当前系统时间值,

    • password默认为“123456”

  • 包含有参构造(String username, String password),

    • 输出“新用户注册”,

    • registrationTime赋值为当前系统时间,

    • username和password由参数赋值

  • 包含public String getInfo()方法,返回:“用户名:xx,密码:xx,注册时间:xx”

(2)编写测试类,测试类main方法的代码如下:

    public static void main(String[] args) {  
        User u1 = new User();  
        System.out.println(u1.getInfo());  
​  
        User u2 = new User("song","8888");  
        System.out.println(u2.getInfo());  
    }

如果不用非静态代码块,User类是这样的:

package com.atguigu.block.no;  
​  
public class User {  
    private String username;  
    private String password;  
    private long registrationTime;  
​  
    public User() {  
        System.out.println("新用户注册");  
        registrationTime = System.currentTimeMillis();  
        username = registrationTime+"";  
        password = "123456";  
    }  
​  
    public User(String username,String password) {  
        System.out.println("新用户注册");  
        registrationTime = System.currentTimeMillis();  
        this.username = username;  
        this.password = password;  
    }  
​  
    public String getUsername() {  
        return username;  
    }  
​  
    public void setUsername(String username) {  
        this.username = username;  
    }  
​  
    public String getPassword() {  
        return password;  
    }  
​  
    public void setPassword(String password) {  
        this.password = password;  
    }  
​  
    public long getRegistrationTime() {  
        return registrationTime;  
    }  
    public String getInfo(){  
        return "用户名:" + username + ",密码:" + password + ",注册时间:" + registrationTime;  
    }  
}

如果提取构造器公共代码到非静态代码块,User类是这样的:

package com.atguigu.block.use;  
​  
public class User {  
    private String username;  
    private String password;  
    private long registrationTime;  
​  
    {  
        System.out.println("新用户注册");  
        registrationTime = System.currentTimeMillis();  
    }  
​  
    public User() {  
        username = registrationTime+"";  
        password = "123456";  
    }  
​  
    public User(String username, String password) {  
        this.username = username;  
        this.password = password;  
    }  
​  
    public String getUsername() {  
        return username;  
    }  
​  
    public void setUsername(String username) {  
        this.username = username;  
    }  
​  
    public String getPassword() {  
        return password;  
    }  
​  
    public void setPassword(String password) {  
        this.password = password;  
    }  
​  
    public long getRegistrationTime() {  
        return registrationTime;  
    }  
    public String getInfo(){  
        return "用户名:" + username + ",密码:" + password + ",注册时间:" + registrationTime;  
    }  
}

举例2:

private static DataSource dataSource = null;  
​  
static{  
    InputStream is = null;  
    try {  
        is = DBCPTest.class.getClassLoader().getResourceAsStream("dbcp.properties");  
        Properties pros = new Properties();  
        pros.load(is);  
        //调用BasicDataSourceFactory的静态方法,获取数据源。  
        dataSource = BasicDataSourceFactory.createDataSource(pros);  
    } catch (Exception e) {  
        e.printStackTrace();  
    }finally{  
        if(is != null){  
            try {  
                is.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }         
        }         
    }         
}

4. 小结:实例变量赋值顺序

image-20220325230208941

Java基础

main方法

2025-8-9 10:29:31

Java基础

枚举类

2025-8-9 14:44:27

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索