[Java – S3] Biến

Xin chào các bạn, lại gặp lại mọi người trong số thứ 3 của chuyên mục Lập trình Java. Trong phần này, mình và các bạn  sẽ cùng tìm hiểu về các loại biến, cách khai báo cũng như cách sử dụng chúng như thế nào. Nội dung chính bao gồm:

  • Biến là gì?
  • Phân loại biến
  • Khai báo vào khởi tạo biến
  • Literals
  • Constant (hằng số)

Biến là gì?

Như ta đã biết, biến là một địa chỉ lưu trữ, được liên kết với một kiểu dữ liệu, nguyên thủy hoặc tham chiếu. Các biến nguyên thủy (primitive variable) lưu giá trị thực trên stack, trong khi đó các biến tham chiếu lưu địa chỉ  của đối tượng trong bộ nhớ heap mà nó tham chiếu đến. Vì vậy, các biến nguyên thủy thường được gán giá trị mặc định của kiểu dữ liệu khi khai báo không khởi tạo. Các biến tham chiếu nếu không được khởi tạo, sẽ không tham chiếu tới đối tượng nào trong bộ  nhớ và nhận giá trị null.

su-khac-nhau-giua-kieu-du-lieu-ngyen-thuy-va-kieu-du-lieu-tham-chieu-trong-java
Hình 3.1 Sự khác nhau giữa kiểu dữ liệu nguyên thủy và kiểu dữ liệu tham chiếu trong Java

Biến tham chiếu được ví như chiếc điều khiển từ xa, có khả năng truy cập từ bên ngoài (class, package khác) đến các phương thức hay các biến instance thông qua toán tử ‘.’ (tất nhiên còn phụ thuộc vào access modifier của các phương thức hoặc biến đó).

Mảng (tập hợp các phần tử cùng kiểu dữ liệu) là một biến tham chiếu (một đối tượng), mặc dù nó có thể được khai báo là chứa các phần tử nguyên thủy.

Phân loại biến

Ngôn ngữ lập trình Java định nghĩa 4 loại biến:

  • Biến Instance (Non-Static Fields)
    • Là các biến không chứa từ khóa static, được khai báo bên trong class nhưng bên ngoài các phương thức
    • Các biến instance có thể truy xuất được mọi nơi trong class (trừ các hàm static), và những nơi bên ngoài class mà kiểu access modifier của biến đó cho phép
  • Biến Class (Static Fields)
    • Là các biến có chứa từ khóa static, được khai báo bên trong class nhưng bên ngoài các phương thức
    • Các biến static được cấp phát bộ nhớ một lần duy nhất khi class được load. Một class được load bởi khối ClassLoader trong máy ảo Java (JVM) khi một trường hợp cụ thể (một object, một instance) của class đó được khởi tạo, hay có một truy xuất đến các biến (hàm) static của class đó
    • Có giá trị không phụ thuộc vào số đối tượng được tạo ra (có giá trị như nhau đối với các đối tượng khác nhau)
    • Bộ nhớ cấp phát cho các biến static chỉ được giải phóng khi kết thúc chương trình. Vì vậy, các biến static nên được hạn chế sử dụng để tránh memory leak
    • Có khả năng truy cập các biến bên ngoài class mà không cần khởi tạo một đối tượng của class đó

    Biến instance và biến class đại diện cho các trường trong class. Các biến class đại diện cho các trường tĩnh, không thể thay đổi được (về mặt đối tượng, không phải về mặt giá trị), luôn đi theo class nên được gọi là biến class. Các biến instance  đại diện cho các trường có thể thay đổi được, các thể hiện khác nhau của class (các object, các instance) thì giá trị của biến instance (thuộc tính) khác nhau, nên được gọi là biến instance.

  • Biến Local
    • Biến local là các biến non-static bên trong một phương thức hay một khối (không thể khai báo một biến trong một phương thức hay một khối)
    • Các biến local không thể truy xuất trực tiếp từ bên ngoài phương thức mà nó được khai báo (nếu muốn truy xuất giá trị của biến local, ta có thể truy xuất gián tiếp thong qua giá trị trả về của phương thúc đó)
    • Bộ nhớ cấp phát cho các biến local được giải phóng ngay khi phương thức kết thúc
    • Các biến local không được chỉ định giá trị mặc định. Vì vậy ta phải gán cho biến local một giá trị trước khi sử dung
  • Tham số (Parameters)
    • Nếu như khái niệm tham số trong phần Java – S1 chưa làm các bạn clear, hãy hiểu đơn giản tham số (nếu có) là một hay một vài biến đi kèm theo phương thức và luôn phải truyền vào cho nó một giá trị (cùng kiểu dữ liệu) khi phương thức được gọi đến
    • Giá trị truyền vào đó gọi là đối số. Trong nhiều trường hợp, đối số có thể là một literal, một hang số (xem bên dưới), giá trị của một biến, thậm chí là giá trị trả về của một hàm khác. Xin nhắc lại, trong trường hợp sử biến, cái truyền vào là giá trị của biến đó chứ không phải ô nhớ của biến đó, vì thế giá trị của biến truyền vào không bị thay đổi

Khai báo và khởi tạo biến

Cú pháp:

        access_modifier static (đối với các biến class) data_type variable_name; // khai báo không khởi tạo
hoặc access_modifier static (đối với các biến class) data_type variable_name = value; // khai báo đồng thời khởi tạo

  • access_modifier(public, protected, hoặc private) là các mức truy cập, đại diện cho khả năng truy xuất đến biến. Nếu không điền gì thì mức truy cập là default
  • static: Từ khóa được thêm vào các biến static, không thêm vào biến instance và biến local.
  • data_type: Kiểu dữ liệu nguyên thủy hoặc tham chiếu
  • variable_name: tên biến, được đặt theo các quy ước đặt tên của Java, không trùng với các từ khóa
  • = : Toán tử gán, chỉ định giá trị bên phải cho biến ở bên trái
  • value Một giá trị xác định, đại diện cho kiểu dữ liệu của biến, có thể là một literal, một contants hoặc một đối tượng…
  •  Ký tự kết thúc câu lệnh

public static int age = 15;
private String mColor = "blue"; // private String mColor = new String ("color"); is OK
Dog bitch = new Dog();
...

Literals

Trong ví dụ trên, chúng ta có thể thấy các biến tham chiếu có thể sử dụng từ khóa new để khởi tạo. Tuy nhiên điều này không được áp dụng với các biến kiểu nguyên thủy. Chúng ta có thể truyền trực tiếp một giá trị cố định, không yêu cầu tính toán, đại diện cho một kiểu dữ liệu, cho các biến này. Các giá trị đó, người ta gọi là Literals.

int num1 = 4; // 4 is a literal
String str = "Hello World"; // "Hello World" is s literal.
int num2 = 3 * 5; // 3*5 is not literal.(1)

Hằng số (Constant)

Hằng là một đại lượng có giá trị không thể thay đổi trong một vòng đời của chương trình. Để khai báo hằng, người ra thêm vào khai báo biến từ khóa final static. Vì vậy, hằng có tất cả các tính chất của một biến static. Các hằng số hay dùng thường được khai báo chung trong một  lớp Constants, và được truy xuất khi nào cần thiết như một biến static.

Ngoài ra, từ khóa final cũng có thể thêm vào các biến instance, biến local, thậm chí là các tham số, với ý nghĩa “không thay đổi giá trị được” (điều này có vẻ hơi mâu thuẫn với khái niệm biến nhưng nhiều khi người ta vẫn coi các biến final như một biến). Trong phần hướng đối tượng trong Java, chúng ra còn sử dụng final cho phương thức (với ý nghĩa không thể ghi đè phương thức đó) và class (với ý nghĩa không thể kế thừa class).


public static final String INPUT = "This is s String constant";

Trả lời

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *