常量

“朋友,你知道在 Java 中並不是所有的變量都可以改變嗎?”

“怎麼樣,金?的確,‘可變’這個詞本身就代表著變化。”

“這一點毫無疑問。與許多其他編程語言一樣,Java 具有常量,即其值無法更改的變量。而‘常量’這個詞本身就是恆常性。”

“它們是做什麼用的?”

“通常,它們用於某種基本事物,例如Pi一年中幾個月的天數或天數。也就是說,原則上,程序員可以將任何變量設為常量,如果他或她決定這樣做的話所以是必要的。”

“你的意思是像名字、汽車的顏色或星期幾的名字?”

“你的想法是正確的。任何不應該改變的東西。”

“這些常量在 Java 中是什麼樣子的?”

“Java 有一個特殊的關鍵字:final。創建一個不可變變量看起來與創建一個普通變量一樣。唯一的區別是在變量類型之前你需要寫這個詞final,如下所示:

final Type name = value;

“如果您創建一個常量然後嘗試為其分配不同的值,會發生什麼情況?”

“這是正確的問題!正確的答案是:如果你試圖為變量分配不同的值final,那麼你的程序根本無法編譯。”

“如果你聲明了一個final變量但沒有給它賦值呢?”

“這樣做沒有意義,所以在 Java 中也是不允許的。一個final變量必須在聲明時初始化,也就是說,你必須給它賦值。這個規則有一個例外:你可以移動初始化一個靜態類變量到一個構造函數中。但是你稍後會了解到這一點。

“也就是說,並不是所有的東西都是final常量。為了減少關鍵字的數量,Java 開發人員使用這個詞final不僅僅用於聲明常量。final還可以應用於方法甚至類。聲明為的方法final不能被覆蓋,而類宣佈為final不能繼承。”

“呃……覆蓋?繼承?你現在說的是什麼語言?”

“面向對象編程的語言。你很快就會掌握它。在那之前,盡情享受美麗的術語吧。”

“好的。那麼,final可以放在變量、類和方法之前,這個關鍵字使它們在某種意義上是不可變的嗎?”

“是的。此外,final修飾符可以添加在任何變量之前:局部變量、方法參數、類字段和靜態類變量。

“這裡有一件重要的事情要記住:final在變量名之前只是為了防止對該變量進行任何更改。如果變量存儲了對對象的引用,那麼該對象仍然可以更改。”

“我不太明白。”

“你很快就會明白的。這是一個例子:

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

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

data[0] = 0;
data[1] = 0;
data[2] = 0;
我們創建一個數組。

這是不允許的:變量data聲明為final.

但你可以做到這一點。
還有這個。

“明白了。這很棘手。”

全局常量

“你認為全局常數是什麼?”

“我猜全局常量可能就像全局變量一樣,只是常量?”

“沒錯。如果你需要在你的程序中聲明全局常量,創建靜態類變量,並使它們publicfinal。這種變量的名稱有一種特殊的風格:它們全部用大寫字母書寫,下劃線用於分開的話。

例子:

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;
}

可變陰影

“正如我之前所說,你不能在一個方法中創建多個同名的局部變量。在不同的方法中,你可以。”

“我知道!”

“但是您可能不知道的是,類中的變量和方法中的局部變量很可能具有相同的名稱。

例子:

代碼 可變可見性
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, sum
count, sum
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

“在add方法中,我們聲明了一個名為 的局部變量sum。在方法結束之前,它會隱藏(或屏蔽sum實例變量。”

“嗯......我會說在某種意義上這是預期的行為。”

“但這不是故事的結局。事實證明,如果一個實例變量被局部變量遮蔽,仍然有一種方法可以在方法中引用該實例變量。我們通過在其名稱前寫關鍵字來this實現:

this.name

“這是成功解決名稱衝突的示例:

代碼 可變可見性
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.sum
this.count, this.sum
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

和變量在count任何sum地方都可以使用或不使用this關鍵字。sum在局部變量覆蓋實例變量的行中sumsum只能使用this關鍵字訪問實例變量。

“顯然,我需要練習這個。”

“你會處理的。”

“如果一個靜態類變量被隱藏而不僅僅是一個(非靜態)實例變量怎麼辦?你不能通過它訪問它this?”

“你是對的。這個關鍵字不起作用。你需要通過類名來引用它:

ClassName.name

例子:

代碼 可變可見性
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

“請注意:無論是否使用類名作為前綴,您都可以在任何地方訪問count和靜態變量。在局部變量隱藏實例變量的那些行中,只有在作為前綴使用時才能訪問類變量。sumSolutionsumsumsumSolution

for循環內的變量

“還有一個小但有趣的事實。還有一個地方可以用特殊的方式聲明變量——我說的是在循環內部for ” 通常,循環在括號中for有一個變量。counter這個變量的可見性是什麼?畢竟,它不在循環體內。是整個方法嗎?或不?”

for“我已經聽說過這件事。據我了解,在循環標頭中聲明的變量僅在循環體循環標頭for中可見。”

“幹得好,阿米戈。但是,還是看一個例子來強化這個材料:

代碼 可變可見性
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

“所以你是說,在我的代碼中,我可以用一個同名的計數器變量一個接一個地寫幾個循環,不會有問題嗎?”

“不會有問題的。看這裡:

代碼 可變可見性
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