1. Hằng số

Nhiều ngôn ngữ lập trình khác có các hằng số , nghĩa là các biến có giá trị không thể thay đổi được . Thông thường, chúng được sử dụng cho một số loại điều cơ bản chẳng hạn như số Pihoặc số ngày trong các tháng trong năm. Điều đó nói rằng, về nguyên tắc, một lập trình viên có thể biến bất kỳ biến nào thành hằng số, nếu người đó quyết định rằng làm như vậy là cần thiết.

Vậy làm thế nào để bạn khai báo một biến bất biến (hằng số) trong Java? Có một từ khóa đặc biệt cho việc này: final. Tạo một biến bất biến giống như tạo một biến thông thường. Điểm khác biệt duy nhất là trước kiểu của biến bạn cần viết từ final, như sau:

final Type name = value;

Nếu bạn cố gắng gán một giá trị khác cho một finalbiến, thì chương trình của bạn sẽ không biên dịch được.

Một finalbiến phải được khởi tạo (một giá trị phải được gán cho nó) khi nó được khai báo. Có một ngoại lệ đối với quy tắc này: bạn có thể di chuyển phần khởi tạo của một biến lớp tĩnh thành một hàm tạo. Nhưng bạn sẽ học về điều này ở Cấp độ 10 .

Để giảm số lượng từ khóa, các nhà phát triển Java sử dụng từ này finalnhiều hơn là chỉ khai báo các hằng số. finalcũng có thể áp dụng cho các phương thức và thậm chí cả các lớp. Các phương thức được khai báo là finalkhông thể bị ghi đè và một lớp được khai báo là finalkhông thể kế thừa.

Công finalcụ sửa đổi có thể được thêm vào trước bất kỳ biến nào: biến cục bộ, tham số phương thức, trường lớp và biến lớp tĩnh.

Lưu ý rằng finaltrước một tên biến chỉ là bảo vệ chống lại bất kỳ thay đổi nào đối với biến đó . Nếu một biến lưu trữ một tham chiếu đến một đối tượng, thì đối tượng đó vẫn có thể được thay đổi.

Ví dụ:

final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
Chúng tôi tạo một mảng.

Điều này không được phép: biến datađược khai báo là final.

Nhưng bạn có thể làm điều này.
Và cả điều này nữa.

hằng số toàn cầu

Nếu bạn quyết định khai báo các hằng số toàn cầu trong chương trình của mình, thì bạn cần tạo các biến lớp tĩnh và tạo chúng publicfinal. Có một kiểu đặc biệt cho tên của các biến như vậy: chúng được viết bằng tất cả các chữ in hoa, với một ký tự gạch dưới được sử dụng để phân tách các từ.

Ví dụ:

class Solution
{
   public static final String SOURCE_ROOT = "c:\\projects\\my\\";
   public static final int DISPLAY_WIDTH = 1024;
   public static final int DISPLAY_HEIGHT = 768;
}


2. Tạo bóng thay đổi

Như chúng tôi đã nói trước đây, bạn không thể tạo nhiều biến cục bộ có cùng tên trong cùng một phương thức. Trong các phương pháp khác nhau, bạn có thể.

Nhưng đây là điều có thể bạn chưa biết: biến thể hiện và biến phương thức cục bộ có thể có cùng tên.

Ví dụ:

Mã số khả năng hiển thị thay đổi
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     sum = sum + data;
     int sum = data * 2;
     count++;
   }
}


count
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

Trong addphương thức này, chúng ta đã khai báo một biến cục bộ có tên là sum. Cho đến khi kết thúc phương thức, nó sẽ che khuất (hoặc che khuất ) sumbiến đối tượng.

Được rồi, bạn nói, điều đó được mong đợi theo một nghĩa nào đó. Nhưng đó không phải là kết thúc của câu chuyện. Nó chỉ ra rằng nếu một biến thể hiện bị che khuất bởi một biến cục bộ, thì vẫn có cách để tham chiếu đến biến thể hiện trong phương thức. Chúng tôi làm điều này bằng cách viết thistừ khóa trước tên của nó:

this.name

Đây là một ví dụ trong đó xung đột tên được giải quyết thành công:

Mã số khả năng hiển thị thay đổi
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     this.sum = this.sum + data;
     count++;
   }
}


this.count
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum, data
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum

Các biến count và sum có sẵn ở mọi nơi có hoặc không có thistừ khóa. Trên các dòng mà sum biến cục bộ che khuất sumbiến thể hiện, sum biến thể hiện chỉ có thể được truy cập bằng thistừ khóa.

Nếu một biến lớp tĩnh chứ không phải một biến thể hiện bị che khuất, thì bạn cần truy cập nó thông qua tên lớp thay vì từ thiskhóa:

ClassName.name

Ví dụ:

Mã số khả năng hiển thị thay đổi
public class Solution
{
   public static int count = 0;
   public static int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     Solution.sum = Solution.sum + data;
     count++;
   }
}

Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum, data
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum

Bạn có thể truy cập các biến count và sum tĩnh ở mọi nơi có hoặc không sử dụng tên lớp Solutionlàm tiền tố. Trong những dòng mà sumbiến cục bộ che khuất biến thể hiện,  chỉ có thể sumtruy cập vào biến thể hiện khi sử dụng làm tiền tố.sumSolution



3. Biến bên trong forvòng lặp

Và một sự thật nhỏ nhưng thú vị nữa.

Cũng có một nơi mà một biến được khai báo theo một cách đặc biệt — bên trong một forvòng lặp .

Bạn có thể nhớ rằng một forvòng lặp thường có một biến đếm trong ngoặc đơn. Và khả năng hiển thị của biến này sẽ như thế nào? Rốt cuộc, nó không nằm trong phần thân của vòng lặp. Có phải là toàn bộ phương pháp? Hay không?

Câu trả lời đúng là: một biến được khai báo trong tiêu đề của forvòng lặp chỉ hiển thị trong phần thân của vòng lặp và trong tiêu đề của forvòng lặp .

Ví dụ:

Mã số khả năng hiển thị thay đổi
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a

Vì vậy, bạn luôn có thể viết các vòng lặp lần lượt trong mã của mình và sử dụng các biến bộ đếm có cùng tên — điều đó sẽ không tạo ra bất kỳ vấn đề nào.

Ví dụ:

Mã số khả năng hiển thị thay đổi
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a, i
a, i
a, i
a
a
a