99 Ngày Java — Ngày 04: Toán tử & biểu thức
Hôm qua bạn đã có những chiếc hộp dữ liệu — biến và 8 kiểu nguyên thủy. Hôm nay ta cho chúng "nói chuyện" với nhau bằng toán tử: cộng trừ nhân chia, so sánh, logic, toán tử 3 ngôi — và bẫy độ ưu tiên khiến 2 + 3 * 4 không bằng 20.

Toán tử số học
Năm toán tử quen thuộc: + - * / %. Nhưng Java có một bất ngờ lớn cho người mới: hai số nguyên chia nhau ra số nguyên — phần thập phân bị cắt bỏ không thương tiếc:
int a = 7, b = 2;
System.out.println(a + b); // 9
System.out.println(a - b); // 5
System.out.println(a * b); // 14
System.out.println(a / b); // 3 — chia NGUYÊN: phần thập phân bị cắt!
System.out.println(a % b); // 1 — số dư (modulo)
System.out.println(7.0 / 2); // 3.5 — có double tham gia là chia thựcToán tử % (lấy dư) hữu ích hơn vẻ ngoài của nó: n % 2 == 0 kiểm tra số chẵn, index % size quay vòng chỉ số mảng, seconds % 60 tách phút–giây. Còn phép chia nguyên 7 / 2 = 3 là nguồn bug kinh điển khi tính trung bình, tỷ lệ phần trăm — chỉ cần một vế là double (viết 7.0 hoặc cast) là phép chia thành chia thực.
++ và -- : prefix vs postfix
int i = 5;
System.out.println(i++); // in 5, SAU ĐÓ i mới thành 6 (postfix)
System.out.println(++i); // i thành 7 TRƯỚC, rồi mới in 7 (prefix)
int j = 5;
int k = j++ + ++j; // đọc được, nhưng đừng viết thế này!i++(postfix) — dùng giá trị cũ trước, tăng sau.++i(prefix) — tăng trước, rồi mới dùng giá trị mới.Đứng một mình (
i++;) thì hai dạng như nhau — và đó là cách dùng nên theo: đừng nhét++vào giữa biểu thức phức tạp.
Toán tử gán kết hợp
x += 5 là cách viết gọn của x = x + 5 — tương tự có -=, *=, /=, %=. Một chi tiết ít người biết: toán tử gán kết hợp tự ép kiểu ngầm — byte b = 10; b += 1; chạy ngon, trong khi b = b + 1; lỗi compile vì b + 1 là int. Chuyện ép kiểu này chính là chủ đề của Ngày 05.
So sánh & logic — và short-circuit
Toán tử so sánh (==, !=, >, <, >=, <=) trả về boolean, rồi được ghép bằng logic && (VÀ), || (HOẶC), ! (PHỦ ĐỊNH):
int age = 20;
boolean hasTicket = true;
boolean canEnter = age >= 18 && hasTicket; // true
// Short-circuit: vế phải KHÔNG chạy nếu vế trái đã đủ kết luận
String name = null;
if (name != null && name.length() > 0) {
// an toàn: name.length() chỉ chạy khi name != null
}Short-circuit là tính năng chứ không phải chi tiết vặt: && thấy vế trái false là dừng ngay, || thấy vế trái true là dừng ngay. Nhờ vậy mẫu name != null && name.length() > 0 trở thành thành ngữ chống NullPointerException mà bạn sẽ gặp ở mọi codebase Java. Lưu ý: với String, so sánh nội dung phải dùng .equals() chứ không phải == — Ngày 09 sẽ mổ xẻ kỹ.
Toán tử 3 ngôi
Toán tử duy nhất nhận 3 toán hạng: điều_kiện ? giá_trị_nếu_đúng : giá_trị_nếu_sai — một biểu thức if-else thu gọn:
int score = 75;
String result = score >= 50 ? "Đậu" : "Rớt"; // "Đậu"
// Tương đương if-else 4 dòng — nhưng chỉ nên dùng khi NGẮN GỌN
int max = a > b ? a : b;Quy tắc vàng: 3 ngôi dùng cho lựa chọn ngắn, một tầng. Lồng 3 ngôi trong 3 ngôi là cách nhanh nhất khiến đồng nghiệp muốn "nói chuyện riêng" với bạn — khi logic phức tạp, quay về if-else (học kỹ ở Ngày 06).
Độ ưu tiên — khi nghi ngờ, thêm ngoặc
int x = 2 + 3 * 4; // 14 — nhân trước, cộng sau
int y = (2 + 3) * 4; // 20 — ngoặc thắng tất cả
boolean t = true || false && false; // true — && trước ||
boolean u = (true || false) && false; // false — ngoặc đổi kết quảThứ tự đại khái cần nhớ:
!→* / %→+ -→ so sánh →&&→||→ gán=cuối cùng.Không ai được thưởng vì thuộc lòng bảng ưu tiên 15 tầng — cứ thêm ngoặc cho người đọc (và chính bạn 6 tháng sau).
Bài tập nhỏ
Không chạy code, đoán kết quả:
9 / 4,9 % 4,9.0 / 4— rồi chạy kiểm tra.Cho
int i = 10;—System.out.println(i++ + ++i)in gì? Giải thích từng bước.Viết biểu thức kiểm tra một năm nhuận: chia hết cho 4 nhưng không chia hết cho 100, hoặc chia hết cho 400.
Dùng toán tử 3 ngôi viết hàm trả về trị tuyệt đối của một số
int.
Kết luận
Bạn đã nắm đủ bộ toán tử: số học và cú lừa chia nguyên, ++/-- hai dạng, so sánh, logic short-circuit, 3 ngôi và quy tắc "thêm ngoặc khi nghi ngờ". Ngày 05, ta giải quyết câu hỏi treo từ hôm nay: chuyện gì xảy ra khi các kiểu khác nhau gặp nhau trong một biểu thức — ép kiểu (casting), widening vs narrowing và bẫy mất mát dữ liệu. Hẹn gặp lại!
Site Admin
Engineer and writer. Building things with TypeScript and distributed systems.
Bình luận (0)
Bạn cần đăng nhập bằng Google để bình luận.
Hãy là người bình luận đầu tiên.


