TungDaDev's Blog

biến, kiểu dữ liệu và toán tử trong java

Java basic.webp
Published on
/14 mins read/

Chào mừng bạn quay trở lại với series Java Core Dành Cho Người Mới Bắt Đầu!

Nếu ở bài trước bạn đã cài đặt môi trường và in ra dòng chữ "Hello World", thì hôm nay chúng ta sẽ bắt đầu chạm vào những viên gạch nền móng quan trọng nhất của mọi chương trình máy tính: Biến (Variables), Kiểu dữ liệu (Data Types) và Toán tử (Operators).

Mục tiêu của bài viết này là giúp bạn:

  • Hiểu bản chất biến và kiểu dữ liệu một cách trực quan, dễ nhớ nhất.
  • Nắm vững cú pháp khai báo và thực hành thành thạo các phép toán thông dụng.
  • Trang bị ngay từ đầu những "bí kíp thực chiến" (như bẫy chia số nguyên, so sánh chuỗi, sai số tiền tệ) để bạn không mắc phải những lỗi ngớ ngẩn mà ngay cả lập trình viên đi làm đôi khi vẫn dính phải!

# biến là gì?

Hãy tưởng tượng trong phòng bạn có nhiều chiếc hộp để cất đồ:

  • Chiếc hộp dán nhãn "Quần áo" chỉ dùng để đựng áo quần.
  • Chiếc hộp dán nhãn "Sách vở" chỉ dùng để chứa sách.
  • Chiếc hộp dán nhãn "Tiền tiết kiệm" dùng để cất tiền.

Trong lập trình, Biến (Variable) chính là một chiếc hộp được dán nhãn đặt trong bộ nhớ máy tính (RAM) để lưu trữ dữ liệu. Dữ liệu bên trong chiếc hộp đó có thể thay đổi được trong suốt quá trình chương trình vận hành.

# cú pháp khai báo biến chuẩn

<Kiểu_Dữ_Liệu> <Tên_Biến> = <Giá_Trị_Khởi_Tạo>;

Ví dụ cụ thể:

public class VariableDemo {
    public static void main(String[] args) {
        // Khai báo một biến kiểu số nguyên tên là 'age' và gán giá trị 20
        int age = 20;
 
        // Khai báo biến chuỗi tên là 'fullName'
        String fullName = "Bùi Thanh Tùng";
 
        // Khởi tạo trước, gán giá trị sau cũng hoàn toàn hợp lệ
        double salary;
        salary = 1500.50;
 
        // In các giá trị ra màn hình Console
        System.out.println("Xin chào: " + fullName);
        System.out.println("Tuổi hiện tại: " + age);
        System.out.println("Mức lương: $" + salary);
 
        // Thay đổi giá trị bên trong biến (đúng như tên gọi 'biến')
        age = 21;
        System.out.println("Tuổi sau sinh nhật: " + age);
    }
}

# quy tắc đặt tên biến chuẩn quốc tế

  1. Dùng quy tắc Lạc Đà (camelCase): Chữ cái đầu viết thường, các từ phía sau viết hoa chữ cái đầu (Ví dụ: totalPrice, userEmail, accountBalance).
  2. Có ý nghĩa rõ ràng: Đặt tên mô tả đúng mục đích (Dùng customerAge, KHÔNG đặt tên cẩu thả như a, b, x1, temp).
  3. Không bắt đầu bằng chữ số: 1user (Sai), user1 (Đúng).
  4. Không trùng với từ khóa của Java: Không đặt tên biến là class, int, public, return.

# hằng số với từ khóa final

Nếu bạn có một giá trị cố định không bao giờ được phép thay đổi (như số PI, thuế VAT, hoặc số ngày trong tuần), hãy thêm từ khóa final. Tên hằng số theo quy ước sẽ viết hoa toàn bộ và nối bằng dấu gạch dưới (UPPER_SNAKE_CASE):

final double PI = 3.14159265359;
final int DAYS_IN_WEEK = 7;
 
// PI = 3.15; // LỖI BIÊN DỊCH! Java cấm thay đổi giá trị của hằng số final.

# các kiểu dữ liệu nguyên thủy & String

Java là ngôn ngữ kiểm tra kiểu tĩnh nghiêm ngặt (Statically Typed). Nghĩa là trước khi cất đồ vào hộp, bạn bắt buộc phải nói rõ chiếc hộp đó đựng loại đồ gì.

Java chia làm 2 nhóm kiểu dữ liệu chính:

  1. Primitive Types (Kiểu nguyên thủy): Gồm 8 kiểu cơ bản có sẵn do ngôn ngữ cung cấp, lưu trữ giá trị thuần túy.
  2. Reference Types (Kiểu tham chiếu / Đối tượng): Các kiểu phức tạp như String, Array, Class, lưu trữ địa chỉ trỏ tới dữ liệu.

# bảng tra cứu 8 kiểu nguyên thủy

Kiểu dữ liệuKích thướcKhoảng giá trị lưu trữVí dụ thực tế trong cuộc sống
byte1 byte-128 đến 127Tuổi con người, số tầng của tòa nhà
short2 bytes-32,768 đến 32,767Năm sinh (1998, 2026), số học sinh một trường
int (Phổ biến nhất)4 bytesKhoảng -2.14 tỷ đến +2.14 tỷLượt xem YouTube, số dư tài khoản thông thường
long8 bytesCực kỳ lớn (khoảng 9.22 triệu tỷ)Dân số thế giới, ID cơ sở dữ liệu lớn (Thêm chữ L ở cuối: 10000000000L)
float4 bytesSố thực có 6–7 chữ số thập phânTọa độ GPS cơ bản (Thêm chữ f ở cuối: 3.14f)
double (Mặc định)8 bytesSố thực có 15–16 chữ số thập phânChiều cao 1.75, điểm số 8.5, vận tốc vật lý
boolean1 bit (logic)Chỉ có 2 giá trị: true hoặc falseTrạng thái đăng nhập (isLoggedIn), đã thanh toán (isPaid)
char2 bytesChứa duy nhất 1 ký tự UnicodeĐặt trong nháy đơn: 'A', 'Z', '8', '@'

# kiểu chuỗi ký tự String

Khác với char chỉ chứa 1 ký tự và dùng nháy đơn ' ', String là một chuỗi văn bản đặt trong dấu nháy kép " ":

char grade = 'A';                   // char: 1 ký tự, nháy đơn
String message = "Học Java dễ ẹc!"; // String: chuỗi chữ, nháy kép

# các toán tử cơ bản trong java

Toán tử là các ký hiệu dùng để thực hiện các phép tính số học, so sánh giá trị hoặc kết hợp điều kiện logic.

# toán tử số học

int a = 10;
int b = 3;
 
System.out.println(a + b); // Cộng: 13
System.out.println(a - b); // Trừ: 7
System.out.println(a * b); // Nhân: 30
System.out.println(a / b); // Chia lấy phần nguyên: 3 (Vì 10 chia 3 được 3 dư 1)
System.out.println(a % b); // Chia lấy phần DƯ (Modulo): 1

TIP

Ứng dụng cực hay của toán tử chia lấy dư %:

  • Kiểm tra số chẵn / lẻ: number % 2 == 0 -> Số chẵn.
  • Chia nhóm hoặc tạo vòng lặp luân phiên.

# toán tử tăng giảm (++ và --)

Dùng để tăng hoặc giảm giá trị của một biến đi 1 đơn vị:

  • a++ hoặc ++a tương đương với a = a + 1;
  • a-- hoặc --a tương đương với a = a - 1;

Sự khác nhau giữa Tiền tố (++a) và Hậu tố (a++):

  • ++a (Tiền tố): Tăng trước rồi mới lấy giá trị đi tính toán.
  • a++ (Hậu tố): Lấy giá trị hiện tại đi tính toán trước, sau đó mới tăng biến lên.
int x = 5;
int y = x++; // y nhận giá trị 5 trước, sau đó x mới tăng lên 6!
System.out.println("x = " + x + ", y = " + y); // x = 6, y = 5
 
int m = 5;
int n = ++m; // m tăng lên 6 trước, sau đó gán giá trị 6 cho n!
System.out.println("m = " + m + ", n = " + n); // m = 6, n = 6

# toán tử so sánh

Luôn trả về kết quả kiểu boolean (true hoặc false):

Toán tửÝ nghĩaVí dụ (x = 10, y = 5)Kết quả
==So sánh bằng nhaux == yfalse
!=So sánh khác nhau (không bằng)x != ytrue
>Lớn hơnx > ytrue
<Nhỏ hơnx < yfalse
>=Lớn hơn hoặc bằngx >= 10true
<=Nhỏ hơn hoặc bằngy <= 4false

# toán tử logic

Dùng để kết hợp nhiều điều kiện lại với nhau:

  • && (VÀ - AND): Trả về true khi TẤT CẢ các điều kiện đều đúng.
  • || (HOẶC - OR): Trả về true khi CHỈ CẦN 1 điều kiện đúng.
  • ! (PHỦ ĐỊNH - NOT): Đảo ngược trạng thái (!true thành false, !false thành true).
int age = 22;
boolean hasDrivingLicense = true;
 
// Bạn chỉ được lái xe khi đủ 18 tuổi VÀ có bằng lái:
boolean canDrive = (age >= 18) && hasDrivingLicense;
System.out.println("Được phép lái xe? " + canDrive); // true
 
// Được giảm giá vé nếu là trẻ em (< 12 tuổi) HOẶC người cao tuổi (> 60 tuổi):
boolean hasDiscount = (age < 12) || (age > 60);
System.out.println("Được giảm giá? " + hasDiscount); // false

# cạm bẫy thực chiến thường gặp

# phép chia số nguyên bị mất phần thập phân

Hãy xem đoạn code sau:

int a = 5;
int b = 2;
double result = a / b;
System.out.println("5 chia 2 bằng: " + result);
// Bạn mong đợi 2.5? Kết quả in ra lại là: 2.0!

Tại sao lại như vậy? Vì cả a và b đều là kiểu số nguyên (int), Java sẽ thực hiện phép chia nguyên trước: 5 / 2 = 2. Sau đó nó mới gán số 2 này sang kiểu double, biến thành 2.0!

Cách khắc phục: Ép kiểu ít nhất một trong hai số sang kiểu số thực (double):

double result = (double) a / b; // Ép 'a' thành 5.0 -> 5.0 / 2 = 2.5 (Chính xác!)

# so sánh hai chuỗi bằng toán tử ==

String name1 = new String("Tung");
String name2 = new String("Tung");
 
System.out.println(name1 == name2); // IN RA FALSE! TẠI SAO?

Bản chất:

  • Toán tử == đối với kiểu đối tượng (Object/String) chỉ so sánh địa chỉ bộ nhớ (hai người có ở chung một nhà không), chứ không so sánh nội dung bên trong chữ cái!
  • name1 và name2 là hai chiếc hộp độc lập nằm ở hai ô nhớ khác nhau trên RAM, nên == trả về false.

WARNING

Quy Tắc Bất Di Bất Dịch: LUÔN DÙNG .equals() ĐỂ SO SÁNH CHUỖI!

System.out.println(name1.equals(name2)); // IN RA TRUE!

# tại sao 0.1 + 0.2 != 0.3?

Hãy chạy thử đoạn mã thú vị này:

double x = 0.1;
double y = 0.2;
System.out.println(x + y); // In ra: 0.30000000000000004!
System.out.println(x + y == 0.3); // In ra: false!

Lý do: Máy tính hoạt động bằng các bóng bán dẫn chỉ hiểu số nhị phân 0 và 1 (cơ số 2). Giống như trong toán học phân số 1/3 = 0.33333... bị vô hạn tuần hoàn, thì trong hệ nhị phân, số thập phân 0.1 và 0.2 cũng bị vô hạn tuần hoàn và máy tính buộc phải cắt cụt một ít ở đuôi!

Hậu quả: Nếu một ứng dụng ngân hàng dùng double để cộng dồn hàng triệu giao dịch $0.10 đô-la, sai số li ti này sẽ tích lũy thành hàng nghìn đô-la chênh lệch trong sổ sách kế toán!

Giải pháp của kỹ sư: Khi lập trình liên quan đến tiền bạc, hóa đơn, lãi suất, luôn dùng lớp java.math.BigDecimal kèm chuỗi String:

import java.math.BigDecimal;
 
BigDecimal price1 = new BigDecimal("0.1");
BigDecimal price2 = new BigDecimal("0.2");
BigDecimal total = price1.add(price2);
 
System.out.println(total); // In ra chuẩn xác 100%: 0.3

# hiện tượng tràn số integer overflow

Kiểu int chỉ chứa tối đa được đến số 2,147,483,647. Điều gì xảy ra nếu bạn cố tình cộng thêm 1?

int max = Integer.MAX_VALUE; // 2,147,483,647
int overflowed = max + 1;
System.out.println("Kết quả: " + overflowed); // In ra: -2,147,483,648!

Nó không báo lỗi, mà giống như đồng hồ công-tơ-mét xe máy chạy hết vòng sẽ quay ngược lại số âm nhỏ nhất! Bài học: Khi dự tính số liệu có thể vượt quá 2 tỷ (ví dụ ID tài khoản, doanh thu tập đoàn), hãy chọn ngay kiểu long từ đầu!


# bài tập thực hành

Hãy tự tay mở IDE lên, tạo class mới và giải quyết 3 bài toán nhỏ thực tế này nhé:

# bài 1: máy tính chỉ số bmi

  • Khai báo chiều cao (kiểu double, đơn vị mét, ví dụ 1.72) và cân nặng (kiểu double, đơn vị kg, ví dụ 65.5).
  • Tính chỉ số: BMI = Cân nặng / (Chiều cao * Chiều cao).
  • In chỉ số BMI ra màn hình.

# bài 2: máy đổi đơn vị thời gian

  • Cho một biến int totalSeconds = 3665; (tổng số giây).
  • Hãy dùng các toán tử / và % để đổi sang định dạng: bao nhiêu Giờ, bao nhiêu Phút, bao nhiêu Giây? (Gợi ý: 1 giờ = 3600 giây, 1 phút = 60 giây).

# bài 3: kiểm tra điều kiện mua hàng

  • Khai báo biến int accountBalance = 500; (số dư tài khoản) và int itemPrice = 200; (giá món hàng), boolean isStoreOpen = true;.
  • Viết biểu thức boolean kiểm tra xem khách hàng có thỏa mãn cả 2 điều kiện: Số dư >= giá hàng VÀ cửa hàng đang mở cửa hay không?

# kết luận

Trong lập trình, mọi thuật toán phức tạp hay hệ thống trí tuệ nhân tạo đồ sộ suy cho cùng cũng đều được ghép lại từ những chiếc hộp biến và các phép toán cơ bản này.

Chỉ cần bạn nắm chắc:

  1. Chọn đúng kiểu dữ liệu: int cho số nguyên, double cho số thực, boolean cho đúng sai, String cho văn bản.
  2. Cẩn thận phép chia số nguyên và luôn dùng .equals() để so sánh chuỗi.
  3. Tiền bạc thì nhớ tới BigDecimal.

Bạn đã có một nền tảng vững vàng hơn 80% người mới học rồi đấy! Trong bài tiếp theo, chúng ta sẽ bước vào thế giới của Câu lệnh điều kiện if-else và Vòng lặp for/while để bắt đầu ra lệnh cho máy tính tự đưa ra quyết định!

Chúc các bạn học tập vui vẻ! Nếu có bất kỳ thắc mắc nào, đừng ngần ngại để lại câu hỏi để chúng ta cùng thảo luận nhé! 🚀


Chỉ là những ghi chép cá nhân với hy vọng mang lại chút giá trị. Nếu thấy hữu ích, đừng ngại chia sẻ cho bạn bè & đồng nghiệp nhé!

Happy coding 😎 👍🏻 🚀 🔥.