2.1. Khái niệm về biến :
Java là ngôn ngữ định kiểu tĩnh mạnh mẽ (Strongly Typed). Mọi biến đều phải được khai báo kiểu dữ liệu rõ ràng trước khi sử dụng.
- Biến là một tên gọi (identifier) dùng để tham chiếu đến một vùng nhớ, nơi lưu trữ dữ liệu trong chương trình. Nói cách khác, biến là “hộp chứa” dữ liệu để ta có thể sử dụng, thay đổi và xử lý trong quá trình chạy chương trình.
- Tác dụng của biến: Lưu trữ dữ liệu chính xác trong bộ nhớ và xử lý logic các điều kiện, vòng lặp giải thuật.
Ý nghĩa của biến: Cung cấp đầy đủ các khối xây dựng cơ bản để lập trình viên giải quyết mọi bài toán thuật toán và nghiệp vụ.
2.2. Các loại biến trong Java
Trong Java, biến là đơn vị lưu trữ cơ bản của chương trình, được xác định bởi định danh (tên biến), kiểu dữ liệu, phạm vi truy cập và vòng đời tồn tại. Dựa vào vị trí khai báo và cách thức cấp phát bộ nhớ, Java phân chia biến thành 3 loại chính:
Biến cục bộ (Local Variables)
Vị trí khai báo: Được khai báo bên trong thân một phương thức, hàm khởi tạo (constructor) hoặc trong một khối lệnh
{ ... }(ví dụ: khốiif, vòng lặpfor).Vòng đời & Phạm vi: Biến cục bộ được khởi tạo khi luồng thực thi đi vào khối lệnh và bị hủy ngay khi khối lệnh đó kết thúc. Biến không thể được truy cập từ bên ngoài khối lệnh đã khai báo nó.
Vùng nhớ & Khởi tạo: Lưu trên vùng nhớ Stack. Java không tự động gán giá trị mặc định cho biến cục bộ; lập trình viên bắt buộc phải khởi tạo giá trị cụ thể trước khi sử dụng.
Ví dụ minh hoạ Biến cục bộ trong Java
public class ViDuBienCucBo {
public static void main(String[] args) {
// Biến cục bộ trong hàm main: BẮT BUỘC phải gán giá trị trước khi dùng
int donGia = 15000;
int soLuong = 4;
// Biến cục bộ tính thành tiền
int thanhTien = donGia * soLuong;
System.out.println("Thành tiền: " + thanhTien);
// Biến cục bộ bên trong khối lệnh if
if (thanhTien > 50000) {
String thongBao = "Được miễn phí ship!"; // Chỉ sống trong khối if này
System.out.println(thongBao);
}
// System.out.println(thongBao); // LỖI: Ra ngoài khối if, thongBao đã bị hủy!
}
}
Ghi nhớ là: Biến khai báo ở đâu chỉ sống trong cặp ngoặc { } ở đó, kết thúc khối lệnh là biến sẽ tự động bị xóa khỏi bộ nhớ.
Biến toàn cục của đối tượng (Instance Variables)
Vị trí khai báo: Được khai báo bên trong khối lớp (
class) nhưng nằm ngoài tất cả các phương thức, không có từ khóastaticđi kèm.Vòng đời & Phạm vi: Biến ra đời khi đối tượng được tạo lập bằng toán tử
newvà bị thu hồi khi đối tượng bị trình gom rác (Garbage Collector) tiêu hủy. Mỗi đối tượng (instance) sở hữu một bản sao dữ liệu hoàn toàn độc lập của các biến này.Vùng nhớ & Khởi tạo: Lưu trên vùng nhớ Heap (gắn liền với đối tượng). Nếu không gán giá trị khởi đầu, Java sẽ tự động nạp giá trị mặc định:
0(với số nguyên),0.0(với số thực),false(với boolean) vànull(với kiểu tham chiếu).
Ví dụ về biến toàn cục của đối tượng trong Java
class SinhVien {
// Biến thể hiện: Khai báo trong class, ngoài hàm, không có từ khóa "static"
// Mỗi sinh viên khi tạo ra sẽ có bản sao riêng của các biến này
String maSV;
double diemTB;
public void inThongTin() {
System.out.println("Mã: " + maSV + " | Điểm: " + diemTB);
}
}
public class Main {
public static void main(String[] args) {
// Tạo đối tượng sv1 -> sv1 có vùng nhớ riêng cho maSV và diemTB
SinhVien sv1 = new SinhVien();
sv1.maSV = "SV01";
sv1.diemTB = 8.5;
// Tạo đối tượng sv2 -> sv2 có vùng nhớ riêng biệt hoàn toàn
SinhVien sv2 = new SinhVien();
sv2.maSV = "SV02";
sv2.diemTB = 6.0;
sv1.inThongTin(); // In: Mã: SV01 | Điểm: 8.5
sv2.inThongTin(); // In: Mã: SV02 | Điểm: 6.0
}
}
Ghi nhớ: Biến sinh ra cùng với đối tượng khi dùng new và nằm ở bộ nhớ Heap; mỗi đối tượng sở hữu dữ liệu độc lập, đối tượng này sửa giá trị thì đối tượng kia không bị ảnh hưởng.
Biến tĩnh / Biến của lớp (Class / Static Variables)
Vị trí khai báo: Được khai báo bên trong khối lớp nhưng có từ khóa
staticđứng phía trước.Vòng đời & Phạm vi: Tồn tại xuyên suốt từ khi lớp được nạp vào bộ nhớ JVM cho đến khi chương trình kết thúc. Biến tĩnh đóng vai trò như một biến dùng chung; tất cả các đối tượng được tạo ra từ lớp đó đều chia sẻ chung một ô nhớ duy nhất thay vì tạo bản sao riêng.
Cách truy xuất: Có thể truy xuất trực tiếp thông qua tên lớp mà không cần phải khởi tạo đối tượng:
TenLớp.tenBien.
Ví dụ về biến tĩnh / biến của lớp trong Java
class SinhVien {
// Biến thể hiện: Mỗi sinh viên có tên riêng
String hoTen;
// Biến tĩnh: Có từ khóa "static", dùng chung cho TẤT CẢ các đối tượng
static String tenTruong = "Trung Cấp Nghề Củ Chi";
}
public class Main {
public static void main(String[] args) {
// 1. Gọi trực tiếp qua tên Lớp mà KHÔNG cần tạo đối tượng
System.out.println("Trường: " + SinhVien.tenTruong);
// 2. Các đối tượng cùng chia sẻ chung 1 ô nhớ duy nhất
SinhVien sv1 = new SinhVien();
sv1.hoTen = "Nguyễn Văn An";
SinhVien sv2 = new SinhVien();
sv2.hoTen = "Trần Thị Bích";
// 3. Khi một nơi thay đổi, tất cả đối tượng đều thấy giá trị mới[cite: 2]
SinhVien.tenTruong = "Trường Đổi Tên Mới";
System.out.println(sv1.hoTen + " học tại: " + SinhVien.tenTruong);
System.out.println(sv2.hoTen + " học tại: " + SinhVien.tenTruong);
}
}
Ghi nhớ: Biến tĩnh có từ khóa static, chỉ tồn tại duy nhất một bản sao trong bộ nhớ và nó được truy xuất thẳng qua cú pháp TenLop.tenBien mà không cần new
2.3. Cách khai báo biến trong Java
2.3.1. Cú pháp cơ bản khai báo biến
Trong Java, mọi biến bắt buộc phải được khai báo kiểu dữ liệu rõ ràng trước khi đưa vào sử dụng (ngôn ngữ định kiểu tĩnh). Cú pháp tổng quát có dạng như sau
type identifier [ = value][, identifier [= value]...];
type: Kiểu dữ liệu của biến (có thể là kiểu nguyên thủy nhưint,double,booleanhoặc kiểu đối tượng/tham chiếu nhưString,SanPham).identifier: Tên của biến (phải tuân thủ quy tắc đặt tên định danh trong Java).= value: Thành phần khởi tạo giá trị ban đầu (tùy chọn, có thể gán ngay khi khai báo hoặc gán sau).Dấu phẩy
,: Cho phép khai báo đồng thời nhiều biến có cùng kiểu dữ liệu trên cùng một dòng lệnh.
Ví dụ minh họa:
int a, b, c; // Khai báo 3 biến nguyên a, b, c chưa gán giá trị
int d = 3, e, f = 5; // Khai báo 3 biến nguyên, gán trước giá trị cho d và f
double pi = 3.14159; // Khai báo số thực và gán giá trị
char kyTu = 'X'; // Khai báo ký tự
String hoTen = "Nguyen Van A"; // Khai báo biến tham chiếu kiểu chuỗi
2.3.2. Quy tắc đặt tên biến (Identifiers & Naming Conventions)
- Quy tắc bắt buộc (Compiler rules):Tên biến phải bắt đầu bằng một chữ cái (a–z, A–Z), dấu gạch dưới
_hoặc dấu đô la$.Không được bắt đầu bằng chữ số (ví dụ:
2countlà sai cú pháp).Java phân biệt rạch ròi giữa chữ hoa và chữ thường (
diemTBkhácDiemTB).Tuyệt đối không được trùng với các từ khóa dành riêng của ngôn ngữ Java (như
class,public,int,for,static,…).
Quy ước chuẩn Java (CamelCase Convention):
Tên biến nên viết theo quy tắc lạc đà (lowerCamelCase): Chữ cái đầu tiên viết thường, các từ phía sau viết hoa chữ cái đầu (ví dụ:
soLuongTon,tienLuongThang,ngayVaoLam).Tên biến phải mang tính gợi mở, thể hiện đúng bản chất dữ liệu đang lưu giữ (tránh đặt tên vô nghĩa như
x,y,tempcho các dữ liệu quan trọng).
2.3.3. Khởi tạo động cho biến (Dynamic Initialization)
Java cho phép khởi tạo giá trị cho một biến một cách linh hoạt tại thời điểm chạy (runtime) thông qua bất kỳ biểu thức, hàm toán học hay phép toán nào hợp lệ:
double a = 3.0, b = 4.0;
// Biến c được khởi tạo động thông qua lời gọi hàm căn bậc hai
double c = Math.sqrt(a * a + b * b);
2.3.4. Khai báo hằng số với từ khóa final
Khi một giá trị cần cố định và ngăn chặn mọi thao tác chỉnh sửa trong suốt thời gian chạy chương trình, lập trình viên sử dụng từ khóa final đứng trước kiểu dữ liệu:
Cú pháp:
final type CONSTANT_NAME = value;Quy ước: Tên hằng số thường được viết hoa toàn bộ và nối các từ bằng dấu gạch dưới
_.Ví dụ:
final double SO_PI = 3.141592653589793; final int SO_NGAY_LAM_VIEC_CHUAN = 24; // SO_PI = 3.14; // Lỗi biên dịch: Không thể gán lại giá trị cho hằng số fina
2.4. Các kiểu dữ liệu trong Java
2.4.1. Khái quát về kiểu dữ liệu trong Java
Java là một ngôn ngữ định kiểu tĩnh mạnh mẽ (Strongly Typed). Mọi biến, hằng số và biểu thức đều phải được xác định rõ kiểu dữ liệu trước khi biên dịch. Trình biên dịch Java kiểm soát chặt chẽ tính tương thích về kiểu, không tự ý chuyển đổi ngầm định các kiểu xung đột nhằm đảm bảo an toàn bộ nhớ và ngăn ngừa lỗi lúc thực thi (runtime).
Trong Java, hệ thống kiểu dữ liệu được chia làm 2 nhóm chính:
Kiểu dữ liệu nguyên thủy (Primitive Data Types): Lưu trữ giá trị thực tế của dữ liệu trực tiếp trong bộ nhớ.
Kiểu dữ liệu tham chiếu (Reference Data Types): Lưu trữ địa chỉ tham chiếu trỏ đến đối tượng được cấp phát trên bộ nhớ Heap (như String, Mảng, Class, Interface).
2.4.2. Nhóm kiểu dữ liệu nguyên thủy (Primitive Types)
Java định nghĩa 8 kiểu dữ liệu nguyên thủy độc lập nền tảng, có kích thước cố định trên mọi hệ điều hành (đảm bảo tính tương thích “Write Once, Run Anywhere”). 8 kiểu này được gom vào 4 nhóm:
a. Nhóm số nguyên (Integers)
Tất cả kiểu số nguyên trong Java đều là số có dấu (signed) biểu diễn bằng dạng bù hai (two’s complement):
byte(8-bit): Miền giá trị từ -128 đến 127. Thích hợp để xử lý luồng dữ liệu thô từ mạng hoặc tập tin.short(16-bit): Miền giá trị từ -32.768 đến 32.767.int(32-bit): Miền giá trị từ -2.147.483.648 đến 2.147.483.647. Đây là kiểu số nguyên mặc định và phổ biến nhất trong tính toán, điều khiển vòng lặp và chỉ số mảng.long(64-bit): Miền giá trị từ -9.223.372.036.854.775.808 đến 9.223.372.036.854.775.807. Dùng khi lưu các con số rất lớn; khi gán hằng số bắt buộc thêm hậu tốLhoặcl(ví dụ:10000000000L).
b. Nhóm số thực (Floating-Point Numbers)
Biểu diễn các số có phần thập phân theo chuẩn IEEE-754:
float(32-bit): Số thực độ chính xác đơn. Khi gán hằng số bắt buộc thêm hậu tốFhoặcf(ví dụ:5.75f).double(64-bit): Số thực độ chính xác kép, là kiểu số thực mặc định trong Java. Thích hợp cho các phép tính khoa học, hàm toán học (Math.sqrt,Math.sin) hoặc tính toán tài chính cơ bản.
c. Kiểu ký tự (Character)
char(16-bit): Dùng để lưu trữ một ký tự Unicode độc lập.Miền giá trị từ 0 đến 65.535 (không có giá trị âm).
Ký tự được bao bọc trong cặp dấu nháy đơn
' '(ví dụ:'A','9','\n').
d. Kiểu logic (Boolean)
boolean(1-bit logic): Chỉ nhận một trong hai giá trị hằng số:truehoặcfalse.Trong Java,
truekhông tương đương số 1,falsekhông tương đương số 0 (không thể ép kiểu qua lại giữa boolean và kiểu số).
2.4.3. Kiểu dữ liệu tham chiếu phổ biến: Lớp chuỗi (String)
Mặc dù không phải là kiểu nguyên thủy, nhưng kiểu chuỗi ký tự được sử dụng thường xuyên như một kiểu dữ liệu cơ bản:
Chuỗi trong Java là một đối tượng thuộc lớp
java.lang.String(viết hoa chữ S).Giá trị chuỗi được đặt trong cặp nháy kép
" ".Chuỗi trong Java có tính chất bất biến (immutable): Giá trị của đối tượng chuỗi một khi đã tạo ra thì không thể bị thay đổi nội dung trên cùng ô nhớ đó.
Ví dụ minh họa về khai báo và sử dụng các kiểu dữ liệu trong Java
package bai1.kieudulieu;
public class DemoKieuDuLieu {
public static void main(String[] args) {
// 1. Nhóm số nguyên
byte tuoi = 18;
int soLuong = 120;
long doanhThu = 15000000000L; // Hậu tố L cho kiểu long
// 2. Nhóm số thực
float diemThi = 7.5f; // Hậu tố f cho kiểu float
double tienLuong = 12500000.75;
// 3. Nhóm ký tự và logic
char kyTuXepLoai = 'A'; // Nháy đơn
boolean quaMon = true; // true hoặc false
// 4. Kiểu chuỗi tham chiếu
String hoTen = "Nguyen Van An"; // Nháy kép
// In kiểm chứng ra màn hình
System.out.println("----- THÔNG TIN HỌC VIÊN -----");
System.out.println("Họ tên: " + hoTen);
System.out.println("Tuổi: " + tuoi + " | Xếp loại: " + kyTuXepLoai);
System.out.printf("Điểm: %.1f | Lương thực tập: %,.0f VNĐ\n", diemThi, tienLuong);
System.out.println("Trạng thái qua môn: " + quaMon);
}
}2.5. Bài tập
Bài tập 1: Quản lý hồ sơ nhân sự (Thực hành khai báo các kiểu dữ liệu nguyên thủy và chuỗi)
Mục tiêu: Rèn luyện việc lựa chọn đúng các kiểu dữ liệu cơ bản (
String,byte/int,double,char,boolean) và in dữ liệu ra console.Yêu cầu:
Khai báo và gán giá trị khởi tạo cho các biến đại diện cho một nhân viên:
hoTen: Kiểu chuỗi ký tự (String).tuoi: Kiểu số nguyên (bytehoặcint).chieuCao: Chiều cao tính theo mét (kiểudoublehoặcfloat, ví dụ:1.72).xepLoaiNgoaiNgu: Xếp loại chứng chỉ ngoại ngữ gồm 1 ký tự A, B hoặc C (kiểuchar).daKetHon: Tình trạng hôn nhân (kiểuboolean, nhận giá trịtruehoặcfalse).
Sử dụng lệnh
System.out.println()vàSystem.out.printf()để xuất toàn bộ hồ sơ của nhân viên ra màn hình.
Bài tập 2: Tính chu vi, diện tích và tính toán hình học (Sử dụng hằng số final và toán tử số học)
Mục tiêu: Thực hành sử dụng từ khóa
finalđể tạo hằng số không thể thay đổi, thực hiện các phép toán số học (+,-,*,/) và hàm toán học cơ bản.Yêu cầu:
Khai báo hằng số số Pi:
final double SO_PI = 3.14159;.Khai báo biến bán kính hình tròn
double banKinh = 5.5;.Tính chu vi và diện tích hình tròn theo công thức:
Chu vi = 2 *PI*banKinh
Diện tích =PI*banKinh^2 (sử dụng phép nhân hoặc
Math.pow())
In kết quả ra màn hình console, làm tròn 2 chữ số thập phân bằng cách sử dụng định dạng
%.2ftrong lệnhSystem.out.printf().
Bài tập 3: Tính toán hóa đơn bán hàng và ép kiểu dữ liệu (Toán tử số học & Casting)
Mục tiêu: Thực hành tính toán biểu thức tiền tệ, phân biệt chia nguyên/chia thực và kỹ thuật ép kiểu dữ liệu (Casting) giữa các kiểu số.
Yêu cầu:
Khai báo các biến:
tenSanPham(chuỗi): ví dụ"Vở kẻ ngang 200 trang".donGia(kiểudouble): ví dụ18500.0.soLuong(kiểuint): ví dụ12.Hằng số thuế VAT:
final double THUE_VAT = 0.08;(8%).
Thực hiện các phép tính:
TienHang = donGia*soLuong
TienThue = TienHang*THUE_VAT
TongThanhToan = TienHang + TienThue
Thực hiện ép kiểu giá trị
TongThanhToan(từ kiểudouble) về một biến số nguyênlong tongTienLamTron(để in số tiền chẵn không lấy phần thập phân).