Trong lập trình Java, toán tử là những ký hiệu đặc biệt được sử dụng để thực hiện các phép toán trên các biến và giá trị. Chúng đóng vai trò quan trọng trong việc thao tác dữ liệu, gán giá trị, so sánh các biểu thức và thực hiện các logic khác nhau trong mã nguồn.
Java cung cấp một tập hợp phong phú các toán tử, được phân loại thành nhiều nhóm chính:
- Toán tử số học: Thực hiện các phép tính toán học cơ bản.
- Toán tử gán: Dùng để gán giá trị cho biến.
- Toán tử so sánh (quan hệ): So sánh hai giá trị và trả về kết quả boolean.
- Toán tử logic: Kết hợp các biểu thức boolean.
- Toán tử bitwise: Thực hiện các phép toán trên từng bit của một số (ít được sử dụng trong lập trình ứng dụng thông thường nhưng có mặt trong các tác vụ cấp thấp hoặc tối ưu hóa).
- Toán tử điều kiện (tam nguyên): Một dạng toán tử gán có điều kiện.
- Toán tử tăng/giảm: Dùng để tăng hoặc giảm giá trị của một biến đi 1 đơn vị.
Toán Tử Số Học
Các toán tử số học được dùng để thực hiện các phép tính cơ bản như cộng, trừ, nhân, chia và chia lấy phần dư. Ngoài ra, có các toán tử đặc biệt để tăng hoặc giảm giá trị.
| Toán Tử | Mô Tả | Ví Dụ | Kết Quả |
|---|---|---|---|
+ |
Dấu dương / Phép cộng | +7 / 10 + 5 |
7 / 15 |
- |
Dấu âm / Phép trừ | int y = 8; -y / 20 - 7 |
-8 / 13 |
* |
Phép nhân | 6 * 4 |
24 |
/ |
Phép chia | 10 / 3 |
3 (chia số nguyên) |
% |
Chia lấy dư (Modulo) | 10 % 3 |
1 |
++ |
Tăng 1 (tiền tố: tăng trước khi dùng) | int a = 5; int b = ++a; |
a=6; b=6 |
++ |
Tăng 1 (hậu tố: dùng trước khi tăng) | int a = 5; int b = a++; |
a=6; b=5 |
-- |
Giảm 1 (tiền tố: giảm trước khi dùng) | int a = 5; int b = --a; |
a=4; b=4 |
-- |
Giảm 1 (hậu tố: dùng trước khi giảm) | int a = 5; int b = a--; |
a=4; b=5 |
+ |
Nối chuỗi | "Xin" + "Chào" |
"XinChào" |
Dưới đây là các ví dụ minh họa cách sử dụng các toán tử số học và tăng/giảm trong Java:
Ví dụ về các phép toán số học cơ bản và chia số thực
class CacPhepToanCoBan {
public static void main(String[] args) {
int soNguyenA = 25;
int soNguyenB = 8;
System.out.println("--- Phép toán số học cơ bản ---");
System.out.println("Tổng: " + (soNguyenA + soNguyenB)); // 25 + 8 = 33
System.out.println("Hiệu: " + (soNguyenA - soNguyenB)); // 25 - 8 = 17
System.out.println("Tích: " + (soNguyenA * soNguyenB)); // 25 * 8 = 200
System.out.println("Thương (nguyên): " + (soNguyenA / soNguyenB)); // 25 / 8 = 3 (phần nguyên)
System.out.println("Số dư (Modulo): " + (soNguyenA % soNguyenB)); // 25 % 8 = 1
// Để có kết quả chia là số thực, cần ép kiểu một trong các toán hạng sang kiểu dấu phẩy động
System.out.println("\n--- Phép chia số thực ---");
double ketQuaChiaThapPhan = (double) soNguyenA / soNguyenB;
System.out.println("Thương (thập phân): " + ketQuaChiaThapPhan); // 25.0 / 8 = 3.125
}
}
Ví dụ về toán tử tăng và giảm
class TangGiamToanTu {
public static void main(String[] args) {
int giaTri = 10;
int ketQua;
System.out.println("--- Toán tử tăng (Increment) ---");
// Tiền tố (Pre-increment): Tăng giá trị trước, sau đó sử dụng giá trị đã tăng
ketQua = ++giaTri;
System.out.println("Sau ++giaTri: giaTri = " + giaTri + ", ketQua = " + ketQua); // giaTri=11, ketQua=11
giaTri = 10; // Đặt lại giá trị
// Hậu tố (Post-increment): Sử dụng giá trị hiện tại trước, sau đó tăng giá trị
ketQua = giaTri++;
System.out.println("Sau giaTri++: giaTri = " + giaTri + ", ketQua = " + ketQua); // giaTri=11, ketQua=10
int soBanDau = 20;
System.out.println("\n--- Toán tử giảm (Decrement) ---");
// Tiền tố (Pre-decrement): Giảm giá trị trước, sau đó sử dụng giá trị đã giảm
ketQua = --soBanDau;
System.out.println("Sau --soBanDau: soBanDau = " + soBanDau + ", ketQua = " + ketQua); // soBanDau=19, ketQua=19
soBanDau = 20; // Đặt lại giá trị
// Hậu tố (Post-decrement): Sử dụng giá trị hiện tại trước, sau đó giảm giá trị
ketQua = soBanDau--;
System.out.println("Sau soBanDau--: soBanDau = " + soBanDau + ", ketQua = " + ketQua); // soBanDau=19, ketQua=20
}
}
Lưu ý về Nâng cấp kiểu dữ liệu tự động (Type Promotion)
Khi thực hiện các phép toán số học trong Java, các kiểu dữ liệu nhỏ hơn int (như byte, short, char) sẽ tự động được nâng cấp (promoted) thành int trước khi phép toán diễn ra. Điều này có thể dẫn đến lỗi biên dịch nếu kết quả của phép toán (là kiểu int) được gán trực tiếp trở lại cho một biến có kiểu dữ liệu nhỏ hơn mà không có ép kiểu tường minh.
class XuLyEpKieu {
public static void main(String[] args) {
short giaTriNgan = 100;
// Ví dụ gây lỗi biên dịch:
// giaTriNgan = giaTriNgan + 1; // Lỗi: kết quả của (giaTriNgan + 1) là int, không thể gán trực tiếp cho short
System.out.println("--- Cách khắc phục ---");
// Giải pháp 1: Ép kiểu tường minh (Explicit Casting)
// Ép kiểu kết quả (int) trở lại short.
short giaTriNganA = 100;
giaTriNganA = (short) (giaTriNganA + 1);
System.out.println("Sau khi dùng ép kiểu tường minh: " + giaTriNganA); // Kết quả: 101
// Giải pháp 2: Sử dụng toán tử tăng/giảm đơn nguyên (Unary Operators: ++ hoặc --)
// Các toán tử này hoạt động trực tiếp trên kiểu dữ liệu của biến mà không gây ra type promotion lên int.
short giaTriNganB = 100;
giaTriNganB++; // Tương đương giaTriNganB = (short)(giaTriNganB + 1);
System.out.println("Sau khi dùng toán tử ++: " + giaTriNganB); // Kết quả: 101
short giaTriNganC = 100;
--giaTriNganC; // Tương đương giaTriNganC = (short)(giaTriNganC - 1);
System.out.println("Sau khi dùng toán tử --: " + giaTriNganC); // Kết quả: 99
}
}