Khối tĩnh
Thuộc phần Lập trình hướng đối tượng trong hành trình Java của Coddy. Bài học 17 trên 87.
Đôi khi, bạn cần khởi tạo các biến tĩnh bằng logic phức tạp hơn một phép gán đơn giản. Khối tĩnh (còn gọi là bộ khởi tạo tĩnh) chạy một lần khi lớp được tải lần đầu, trước khi bất kỳ đối tượng nào được tạo hoặc phương thức tĩnh nào được gọi.
public class DatabaseConfig {
private static String connectionString;
private static int maxConnections;
static {
// Logic khởi tạo phức tạp
connectionString = "jdbc:mysql://localhost:3306/mydb";
maxConnections = 10;
System.out.println("Database configuration loaded");
}
}Khối static (static block) tự động chạy khi lớp được tải vào bộ nhớ. Việc này chỉ xảy ra một lần, bất kể bạn tạo bao nhiêu đối tượng. Khối này rất phù hợp để khởi tạo khi cần nhiều câu lệnh, phép tính hoặc logic điều kiện.
Bạn có thể có nhiều khối static trong một lớp, và chúng chạy theo thứ tự xuất hiện:
public class AppSettings {
private static int[] values;
static {
values = new int[5];
}
static {
for (int i = 0; i < values.length; i++) {
values[i] = i * 10;
}
}
}Các khối lệnh tĩnh thường được dùng để khởi tạo mảng hoặc tập hợp tĩnh, thiết lập các giá trị cấu hình cần tính toán và thực hiện các tác vụ thiết lập một lần ở cấp lớp.
Thử thách
DễHãy tạo một hệ thống GameConfig dùng các khối static để khởi tạo cài đặt trò chơi khi lớp được tải lần đầu. Cách này rất phù hợp với cấu hình cần được tính toán hoặc thiết lập một lần trước khi tạo bất kỳ đối tượng trò chơi nào.
Bạn sẽ tạo hai tệp để sắp xếp code:
GameConfig.java: Tạo một lớp cấu hình khởi tạo các cài đặt bằng các khối static:- Một mảng static riêng tư
levelThresholds(int[]) lưu số điểm cần thiết để đạt từng cấp độ - Một biến static riêng tư
maxLevel(int) lưu tổng số cấp độ - Một biến static riêng tư
configLoaded(boolean) để theo dõi việc khởi tạo đã diễn ra hay chưa - Dùng một khối static để khởi tạo
maxLevelthành 5 và in ra"Initializing game configuration..." - Dùng khối static thứ hai để tạo mảng
levelThresholdscó kích thước bằngmaxLevel, rồi điền vào mảng sao cho mỗi cấp độ cầnlevel * 100điểm (cấp độ 1 cần 100 điểm, cấp độ 2 cần 200 điểm, v.v.), rồi đặtconfigLoadedthànhtrue - Một phương thức static
getThreshold(int level)trả về ngưỡng điểm của cấp độ đó (cấp độ được đánh số bắt đầu từ 1) - Một phương thức static
getMaxLevel()trả về cấp độ tối đa - Một phương thức static
isConfigLoaded()trả về trạng thái cấu hình đã được tải hay chưa
- Một mảng static riêng tư
Main.java: Minh họa rằng các khối static tự động chạy khi lớp được truy cập. Bạn sẽ nhận một đầu vào: số cấp độ cần truy vấn. In ra bốn dòng:Config loaded: truehoặcConfig loaded: falseMax level: [maxLevel]Level [level] threshold: [threshold]Level 1 threshold: [threshold](luôn hiển thị cả cấp độ 1)
Bạn sẽ nhận một đầu vào: số cấp độ (int) cần truy vấn.
Hãy chú ý thông báo khởi tạo được in ra trước khi bất kỳ code nào trong Main chạy. Đó là vì khối static thực thi khi lớp được tải lần đầu!
Tự làm thử
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int level = scanner.nextInt();
// TODO: Truy cập GameConfig để minh họa cách khối lệnh tĩnh chạy
// Các khối lệnh tĩnh trong GameConfig sẽ tự động chạy khi bạn truy cập lớp này lần đầu
// TODO: In ra trạng thái tải config
// Định dạng: "Config loaded: true" hoặc "Config loaded: false"
// TODO: In ra cấp độ tối đa
// Định dạng: "Max level: [maxLevel]"
// TODO: In ra ngưỡng của cấp độ đầu vào
// Định dạng: "Level [level] threshold: [threshold]"
// TODO: In ra ngưỡng của cấp độ 1
// Định dạng: "Level 1 threshold: [threshold]"
}
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcTrường (thuộc tính)Phương thức khởi tạoNạp chồng phương thức khởi tạoÔn tập: Máy tính đơn giản4Kế thừa
Kế thừa cơ bản (extends)Từ khóa superGhi đè phương thức (@Override)Chuỗi gọi hàm khởi tạoLớp ObjectKế thừa đơn và đa cấpVì sao không hỗ trợ kế thừa nhiều lớpÔn tập: Phân cấp lớp Employee7Phương thức đặc biệt và lớp Object
Phương thức toString()equals() và hashCode()Phương thức clone()compareTo() và ComparableGiao diện ComparatorÔn tập: sắp xếp tùy chỉnh2Bộ điều chỉnh quyền truy cập và đóng gói
Tổng quan về các mức truy cậpPhương thức getter và setterẨn thông tinTừ khóa finalÔn tập: Trình quản lý tài khoản ngân hàng5Tính đa hình
Kiến thức cơ bản về nạp chồng phương thứcGhi đè phương thức (thời gian chạy)Chuyển kiểu lên và chuyển kiểu xuốngToán tử instanceofLớp và phương thức trừu tượngÔn tập: máy tính hình học8Khái niệm OOP nâng cao
Kết hợp và kế thừaKết tập và hợp thànhLớp bên trong, lớp lồng nhau và lớp ẩn danhKiểu enum và phương thức enumBản ghi (Java 16+)Lớp sealed (Java 17+)3Thuộc tính lớp và thành viên tĩnh
Biến của instance và biến tĩnhPhương thức tĩnhKhối tĩnhHằng số (static final)Ôn tập: bộ đếm và tiện ích6Giao diện và lớp trừu tượng
Giới thiệu về giao diệnTriển khai giao diệnTriển khai nhiều giao diệnPhương thức mặc định và tĩnh trong giao diệnLớp trừu tượng và giao diệnGiao diện hàmÔn tập: hệ thống thanh toán9Kiểu tổng quát
Giới thiệu về kiểu tổng quátLớp tổng quátPhương thức tổng quátTham số kiểu có giới hạnKý tự đại diện (?, extends, super)Ôn tập: vùng chứa tổng quát12Mẫu thiết kế, phần 2
Mẫu CommandMẫu AdapterMẫu DecoratorMẫu Template MethodMẫu StateMẫu CompositeMẫu IteratorTự luyện tập: Trình biên dịch Java online