目录
4. 类的成员之四:代码块
如果成员变量想要初始化的值不是一个硬编码的常量值,而是需要通过复杂的计算或读取文件、或读取运行环境信息等方式才能获取的一些值,该怎么办呢?此时,可以考虑代码块(或初始化块)。
-
代码块(或初始化块)的
作用
: -
对Java类或对象进行初始化
-
代码块(或初始化块)的
分类
:-
一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块(static block)
-
没有使用static修饰的,为非静态代码块。
-
4.1 静态代码块
如果想要为静态变量初始化,可以直接在静态变量的声明后面直接赋值,也可以使用静态代码块。
4.1.1 语法格式
在代码块的前面加static,就是静态代码块。
【修饰符】 class 类{
static{
静态代码块
}
}
4.1.2 静态代码块的特点
-
可以有输出语句。
-
可以对类的属性、类的声明进行初始化操作。
-
不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
-
若有多个静态的代码块,那么按照从上到下的顺序依次执行。
-
静态代码块的执行要先于非静态代码块。
-
静态代码块随着类的加载而加载,且只执行一次。
4.2 非静态代码块
4.2.1 语法格式
【修饰符】 class 类{
{
非静态代码块
}
【修饰符】 构造器名(){
// 实例初始化代码
}
【修饰符】 构造器名(参数列表){
// 实例初始化代码
}
}
4.2.2 非静态代码块的作用
和构造器一样,也是用于实例变量的初始化等操作。
4.2.3 非静态代码块的意义
如果多个重载的构造器有公共代码,并且这些代码都是先于构造器其他代码执行的,那么可以将这部分代码抽取到非静态代码块中,减少冗余代码。
4.2.4 非静态代码块的执行特点
-
可以有输出语句。
-
可以对类的属性、类的声明进行初始化操作。
-
除了调用非静态的结构外,还可以调用静态的变量或方法。
-
若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
-
每次创建对象的时候,都会执行一次。且先于构造器执行。
4.3 举例
(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方法
如果不用非静态代码块,User类是这样的:
package exer2;
/**
* ClassName:IntelliJ IDEA
* Description:
*
* @Author zyjstart
* @Create:2024/9/5 21:20
*/
public class User {
private String username;
private String password;
private long registrationTime; // 注册时间
// get、set方法
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 User() {
System.out.println("新用户注册");
registrationTime = System.currentTimeMillis(); //获取系统当前时间(距离1970-1-1 00:00:00的毫秒数)
username = System.currentTimeMillis() + "";
password = "123456";
}
public User(String username, String password) {
System.out.println("新用户注册");
registrationTime = System.currentTimeMillis();
this.username = username;
this.password = password;
}
public String getInfo(){
return "用户名:" + username + ", 密码:" + password + ", 注册时间:" + registrationTime;
}
}
如果提取构造器公共代码到非静态代码块,User类是这样的:(这里我重新创建了一个类User1)
package exer2;
/**
* ClassName:IntelliJ IDEA
* Description:
*
* @Author zyjstart
* @Create:2024/9/5 21:30
*/
public class User1 {
private String username;
private String password;
private long registrationTime; // 注册时间
// get、set方法
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;
}
//非静态代码块
{
System.out.println("新用户注册");
registrationTime = System.currentTimeMillis(); //获取系统当前时间(距离1970-1-1 00:00:00的毫秒数)
}
public User1() {
username = System.currentTimeMillis() + "";
password = "123456";
}
public User1(String username, String password) {
// System.out.println("新用户注册");
// registrationTime = System.currentTimeMillis();
this.username = username;
this.password = password;
}
public String getInfo(){
return "用户名:" + username + ", 密码:" + password + ", 注册时间:" + registrationTime;
}
}
执行UserTest类,查看结果
package exer2;
/**
* ClassName:IntelliJ IDEA
* Description:
*
* @Author zyjstart
* @Create:2024/9/5 21:34
*/
public class UserTest {
public static void main(String[] args) {
User u1 = new User();
System.out.println(u1.getInfo());
User u2 = new User("Tom","456789");
System.out.println(u2.getInfo());
System.out.println();
User1 u3 = new User1();
System.out.println(u3.getInfo());
}
}
结果如下
我们将构造器中重复的代码提取出来放到非静态代码块中,每次创建对象时执行,用于初始化。