程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 使用原汁原味的Java語言 - 非Java原生程序員的語言流暢性

使用原汁原味的Java語言 - 非Java原生程序員的語言流暢性

編輯:關於JAVA

學習一種新的編程語言比學習新的口頭語言要容易得多。然而,在這兩種學 習過程中,都要付出額外的努力去學習不帶口音地說新語言。如果您熟悉 C 或 C++,那麼學習 Java 語言並不困難,這就像是會說瑞典語的人去學丹麥語一樣 。語言雖有不同,但又彼此互通。但若不夠謹慎,您的口音每次都會暴露出您並 非原生語言使用者這個秘密。

C++ 程序員往往會對 Java 代碼做出一些變形,而這樣的舉動將他們與原生 Java 語言用戶清晰地區分開來。他們的代碼可以無錯運行,但對於原生語言用 戶來說,就是有一些地方不對勁。因而原生語言用戶可能會輕視非原生用戶。從 C 或 C++(或者 Basic、Fortran、Scheme 等)轉到 Java 語言時,您需要根除 一些習慣用語,並糾正某些發音,以便流暢地使用新語言。

在本文中,我探討了一些往往被忽視的 Java 編程細節,因為從語義上來說 ,它們並不重要,甚至是無關緊要的。它們純粹是風格和慣例問題。其中有些細 節有著似是而非的理由,其他一些甚至連似是而非的理由也沒有。但所有這些細 節都是當今編寫的 Java 代碼中真實存在的現象。

這是什麼語言?

讓我們首先來看一段代碼,其作用是將華氏溫度轉換為攝氏度,如清單 1 所 示:

清單 1. 一段 C 代碼?

float F, C;
float min_tmp, max_tmp, x;

min_tmp = 0;
max_tmp = 300;
x = 20;

F = min_tmp;
while (F <= max_tmp) {
   C = 5 * (F-32) / 9;
   printf("%f\t%f\n", F, C);
   F = F + x;
}

清單 1 中使用的是什麼語言?很顯然是 C 語言 —請等一下,讓我們來看看 完整的程序,如清單 2 所示:

清單 2. Java 程序

class Test {

   public static void main(String argv[]) {
     float F, C;
     float min_tmp, max_tmp, x;

     min_tmp = 0;
     max_tmp = 300;
     x = 20;

     F = min_tmp;
     while (F <= max_tmp) {
      C = 5 * (F-32) / 9;
      printf("%f\t%f\n", F, C);
      F = F + x;
     }
   }

   private static void printf(String format, Object...  args) {
     System.out.printf(format, args);
   }

}

無論您是否相信,清單 1 和清單 2 都是使用 Java 語言編寫的。它們只是 以 C 語言方言(老實說,清單 1 也確實可以是 C 代碼)編寫的 Java 代碼。 這裡的幾個習語標志著:編寫這段代碼的人是以 C 語言思考的,只是單純地將 其翻譯為 Java 語言:

變量是 float 而非 double。

所有變量都是在方法上方聲明的。

初始化緊接聲明之後。

使用了 while 循環而非 for 循環。

使用了 printf 而非 println。

main() 方法的參數名為 argv。

數組括號緊接參數名之後,而非類型之後。

如果僅僅考慮所編寫的這些代碼是否能夠編譯或者是否會得到正確的結果, 那麼這些方言都不是錯誤的。如果分開來看,這幾點都並不明顯。但將它們結合 在一起,就構成了一段非常古怪的代碼,Java 程序員難以讀懂,就像美國人難 以聽懂北英格蘭人的方言一樣。您使用的此類 C 語言方言越少,您的代碼就會 越清晰。請牢記這一點,下面我們將繼續分析 C 語言程序員暴露自己身份的一 些常見方式,並說明如何才能使他們的代碼更符合 Java 程序員的眼光。

命名規范

根據您原本使用的是 C、C++ 還是 C#,您可能有一些較為主觀的類命名規范 。舉例來說,在 C# 中,類名都是以小寫字母開頭的,方法名和字段名以大寫字 母開頭。Java 風格則恰好相反。我沒有任何合理的原因能評判一種規范是否比 另一種更好,但我了解,混用命名規范會使代碼看起來存在嚴重錯誤。這種做法 也會導致 bug。如果您知道,每一個全部由大寫字母組成的名稱都是常量,則會 以不同的方式進行處理。在尋找命名規范與聲明類型不匹配之處時,我發現了程 序中的許多 bug。

args而非 argv

這一點是最微不足道的,但也正是這場風格之爭所關注的細節。在 Java 的 慣例中 main()方法的參數名為 args,而不是 argv:

public static void main(String[] args)

這至多只是對 argv 這個名稱進行了一點細微的改進。作為參數的縮寫,它 或多或少地比 argv 更易懂一些。當然,在合乎慣例的 Java 代碼中,通常是禁 止使用縮寫的(參見 請勿縮寫)。我們使用 args 作為 main() 方法的參數名 的惟一原因與 C 程序員使用 argv 的原因是相同的 — 第一本關於 C 語言的圖 書的作者 Kernighan 和 Ritchie 使用了這個名稱。而 Gosling 和 Arnold 使 用了 args。除此之外,再無其他原因。同樣,所有原生 Java 程序員都傾向於 使用 args,如果您希望保持原汁原味,那麼也應該這樣做。

Java 編程中的基本命名規則非常簡單,也值得牢記:

類和接口名以大寫字母開頭,如 Frame。

方法、字段和本地變量名以小寫字母開頭,如 read()。

類、方法和字段名均使用駝峰式大小寫風格,如 InputStream 和 readFully()。

常量 — 終態靜態字段和臨時終態本地變量 — 全部適用大寫字母,並以下 劃線分隔各詞,如 MAX_CONNECTIONS。

請勿縮寫

像 sprintf 和 nmtkns 這樣的名稱是超級計算機只有 32 KB 內存時代的遺 物。編譯器將標識符限制為 8 個字符或更少,以此來節約內存。近 30 年來, 這已經不再是需要擔心的問題。如今,再沒有任何理由不使用完整拼寫的變量和 方法名稱。難以解讀、無元音字母的變量名清楚地表明這個程序出自一名皈依 Java 的 C 程序員之手,請參見清單 3:

清單 3. Abbrvtd nms r hrd 2 rd

for (int i = 0; i < nr; i++) {
   for (int j = 0; j < nc; j++) {
     t[i][j] = s[i][j];
   }
}

不縮寫、采用駝峰式大小寫風格的名稱更易讀易懂,如清單 4 所示:

清單 4. 未縮寫的名稱更易讀

for (int row = 0; i < numRows; row++) {
   for (int column = 0; column < numColumns;  column++) {
     target[row][column] = source[row][column];
   }
}

一段代碼被閱讀的次數要遠遠超過編寫的次數,Java 語言為易讀性而進行了 優化。C 程序員近乎沉迷於難解的代碼,而 Java 程序員則不然。Java 語言將 易讀性置於簡潔性之前。

有一些極為常用的縮寫形式,您仍然可以放心使用:

max 表示最大(maximum)

min 表示最小(minimum)

in 表示 InputStream

out
表示 OutputStream

e
或 ex 表示 catch 子句中的異常(不用於其他位置)

num 表示數字(number),僅用作前綴,如 numTokens 或 numHits

tmp
表示主要在本地使用的臨時變量 — 針對實例,在交換兩個 值的時候

除此之外(或許還有少數一些例外),您應完整拼寫出名稱中使用的所有詞 。

變量聲明、初始化和使用(重用)

早期版本的 C 需要在方法開始處聲明所有變量。這樣是為了在編譯器中實現 一定的優化,允許它在 RAM 極為有限的環境中運行。因而,C 語言中的方法大 多以幾行變量聲明開頭:

int i, j, k;
double x, y, z;
float cf[], gh[], jk[];

然而,這種風格也有一些缺陷。它將變量的聲明與其使用分離開來,使代碼 的易讀性降低。此外,它會為多種不同的用途重用一個本地變量,有可能並非刻 意而為。但若變量持有代碼的某個片段無法接受的殘值,這可能會帶來無法預料 的 bug。這一點與 C 語言中簡短而難解的變量名結合在一起,將會後患無窮。

在 Java 語言(和較新版本的 C 語言)中,變量可在初次使用或接近初次使 用時聲明。在編寫 Java 代碼時,請采取這種做法。這將使您的代碼更加安全、 更不易出現 bug,也更易於閱讀。

此外,Java 代碼通常在聲明變量時初始化各變量,而 C 程序員有時會寫出 下面這樣的代碼:

int i;
i = 7;

盡管這在語法上是正確的,但 Java 程序員永遠不會寫出這樣的代碼。他們 會這樣寫這段代碼:

int i = 7;

這有助於避免因意外使用了未經初始化的變量而導致的 bug。惟一的常見例 外是一個變量的作用域需要同時包含 try 塊和 catch 或 finally 塊。這往往 是由於代碼涉及需要在 finally 塊中關閉的輸入流和輸出流而導致的,如清單 5 所示:

清單 5. 異常處理可能會使變量的作用域難以合理設定

InputStream in;
try {
  in = new FileInputStream("data.txt");
  // read from InputStream 
}
  finally {
  if (in != null) {
   in.close();
  }
}

但這幾乎是惟一的異常。

這種風格的最後一種連鎖反應就是 Java 程序員通常每行僅聲明一個變量。 例如,他們初始化變量的方法如下:

int i = 3;
int j = 8;
int k = 9;

通常不會寫出下面這樣的代碼:

int i=3, j=8, k=9;

這條語句在語法上是正確的,但除非在一種特殊的例外情況下,專業 Java 程序員是不會這樣做的,後文將介紹這種特殊情況。

老式的 C 程序員甚至可能編寫一個四行的代碼:

int i, j, k;
  i = 3;
  j = 8;
  k = 9;

Java 風格將聲明與初始化結合在一起,因而實際上要更簡練一些,只需要三 行代碼。

將變量置入循環

常見的一種特殊情況就是在循環外部聲明變量。例如,考慮清單 6 中簡單的 for 循環,其作用是計算斐波那契數列的前 20 項:

清單 6. C 程序員喜歡在循環外部聲明變量

int high = 1;
int low = 1;
int tmp;
int i;
for (i = 1; i < 20; i++) {
   System.out.println(high);
   tmp = high;
   high = high+ low;
   low = tmp;
}

所有這四個變量都是在循環外聲明的,盡管它們僅在循環內部使用,但作用 域不止於此。這容易導致 bug,變量可能會在其目標作用域之外被重用。對於使 用常用名的變量來說更是這樣,例如 i 和 tmp。某次使用的值可能會殘留下來 ,並以無法預計的方式干擾後續的代碼。

第一項改進(C 語言的現代版本也支持這項改進)是將 i 循環變量的聲明移 到循環之內,如清單 7 所示:

清單 7. 將循環變量移入循環

int high = 1;
int low = 1;
int tmp;
for (int i = 1; i < 20; i++) {
   System.out.println(high);
   tmp = high;
   high = high+ low;
   low = tmp;
}

到這裡還沒有結束,經驗豐富的 Java 程序員還會將 tmp 變量移入循環,如 清單 8 所示:

清單 8. 在循環內聲明臨時變量

int high = 1;
int low = 1;
for (int i = 1; i < 20; i++) {
   System.out.println(high);
   int tmp = high;
   high = high+ low;
   low = tmp;
}

某些極度追求速度而又不夠老練的開發人員有時會提出反對意見,認為這種 做法導致循環內執行過多操作,而不只是必要的操作,從而降低代碼運行速度。 實際上,在運行時,聲明根本不會執行。將聲明移動到循環內絕不會給 Java 平 台造成負面的性能影響。

許多程序員,包括許多經驗豐富的 Java 程序員都可能在這裡止步。然而, 還有一種不太常見的技巧,將所有變量都移入循環。您可以在 for 循環的初始 化階段聲明多個變量,只需使用逗號分隔即可,如清單 9 所示:

清單 9. 在循環內聲明所有變量

for (int i = 1, high = 1, low = 1; i < 20;  i++) {
   System.out.println(high);
   int tmp = high;
   high = high + low;
   low = tmp;
}

這已經不僅僅是慣用的流暢代碼,而是真正的專業代碼。與 C 代碼相比, Java 代碼中的 for循環更多、while循環更少,原因就在於這種嚴格限制本地變 量作用域的能力。

不要回收變量

上述討論得出這樣一個結論,Java 程序員幾乎不會為不同的值和對象重用本 地變量。例如,清單 10 建立了一些按鈕及其關聯的動作偵聽器:

清單 10. 回收本地變量

Button b = new Button("Play");
  b.addActionListener(new PlayAction());
  b = new Button("Pause");
  b.addActionListener(new PauseAction());
  b = new Button("Rewind");
  b.addActionListener(new RewindAction());
  b = new Button("FastForward");
  b.addActionListener(new FastForwardAction());
  b = new Button("Stop");
  b.addActionListener(new StopAction());

經驗豐富的 Java 程序員會用 5 個不同的本地變量重寫這段代碼,如清單 11 所示:

清單 11. 未回收的變量

Button play = new Button("Play");
  play.addActionListener(new PlayAction());
  Button pause = new Button("Pause");
  pause.addActionListener(new PauseAction());
  Button rewind = new Button("Rewind");
  rewind.addActionListener(new RewindAction());
  Button fastForward = new Button("FastForward");
  fastForward.addActionListener(new FastForwardAction());
  Button stop = new Button("Stop");
  stop.addActionListener(new StopAction());

為多個邏輯上不同的值或對象重用一個本地變量容易導致 bug。實際上,本 地變量(並非始終是它們指向的對象)並不影響內存和時間問題。所以不必為此 擔憂,可以根據您的需要使用多個不同的本地變量。

信任垃圾收集器的內存管理能力

出身 C++ 世界的程序員往往過度擔心內存消耗和內存洩漏問題。此類程序員 有兩種表現。一種是在使用過變量後將變量設置為 null。另一種是調用 finalize()或將其用作一種偽析構函數。這是完全沒有必要的。盡管有些時候確 實需要在 Java 代碼中手動釋放內存,但這種情況十分罕見。大多數時候,只需 依靠垃圾收集器即可合理快速地完成內存管理。與大多數優化一樣,最佳實踐准 則就是:除非能夠證明是有必要的,否則不要去干涉。

使用首選原語數據類型

Java 語言有八種原語數據類型,但僅使用了其中的六種。在 Java 代碼中, float 比 C 代碼中少得多。float 變量或文字在 Java 代碼中極為罕見,更常 用的是 double。使用 float 的惟一時機就是操縱精度有限的大型多維浮點數字 數組,此時存儲空間較為重要。否則使用 double 即可。

比 float 更不常見的是 short。我在 Java 代碼中幾乎沒有見過 short 變 量。只有惟一的一次(我要警告您,這是極其罕見的情況),讀入的外部定義數 據格式碰巧包含 16 位有符號整型類型。在這種情況下,大多數程序員都會將其 作為 int 讀入。

確定私有屬性的范圍

您是否見過清單 22 中這種 equals() 方法?

清單 12. C++ 程序員編寫的 equals()方法

public class Foo {

  private double x;

  public double getX() {
   return this.x;
  }

  public boolean equals(Object o) {
   if (o instanceof Foo) {
    Foo f = (Foo) o;
    return this.x == f.getX();
   }
   return false;
  }

  }

這個方法在技術上是正確的,但我確信,這個類是由一名保守的 C++ 程序員 編寫的。他在一個方法中使用了私有字段 x 和公共 getter 方法 getX(),實際 上是在一行代碼之中,這洩漏了他的身份。在 C++ 中,這種做法是必要的,因 為私有屬性的范圍是對象而不是類。也就是說,在 C++ 中,同一個類的對象無 法看到彼此的私有成員變量。他們必須使用 accessor 方法。在 Java 語言中, 私有屬性的范圍是類而非對象。類型同為 Foo 的兩個對象可直接訪問對方的私 有字段。

某些微妙 — 往往又不相關 — 的考慮思路認為,您應該在 Java 代碼中首 選直接字段訪問而非 getter 訪問,或者反之。字段訪問相對速度較快,但在少 數時候,getter 訪問可能會提供與直接字段訪問略有不同的值,特別是在涉及 子類的時候。在 Java 語言中,沒有任何理由在同一行代碼中為同一個類的同一 個字段同時使用直接字段訪問和 getter 訪問。

標點和語法方言

下面是一些與 C 語言對應部分不同的 Java 方言,在某些情況下,這樣的差 異是為了利用某些 Java 語言特性。

將數組括號緊接於類型之後

Java 語言聲明數組的方式與 C 語言中大致相同:

int k[];
  double temperature[];
  String names[];

但 Java 語言也提供了一種替代性的語法,將數組復括號緊接於類型之後, 而不是變量名之後:

int[] k;
  double[] temperatures;
  String[] names;

大多數 Java 程序員都采用了第二種風格。上面的代碼表示 k 的類型是 int 數組,temperatures 的類型是 double 數組,names 的類型是 String 數組。

同樣,與其他本地變量一樣,Java 程序員習慣在聲明時初始化這些變量:

int[] k = new int[10]; double[] temperatures = new double[75]; String[] names = new String[32];

使用 s == null 而不是 null == s

謹慎的 C 程序員已經學會了將文字置於比較運算符的左側。例如:

if (7 == x) doSomething();

目標在於避免意外地使用單等號賦值運算符而非雙等號比較運算符:

if (7 = x) doSomething();

若將文字置於左側,這樣的錯誤就會成為編譯時錯誤。這項技巧是 C 語言中 一項著名的編程實踐。它能幫助避免出現真正的 bug,因為若將文字置於右端, 將始終返回 true。

然而,不同於 C 語言,Java 語言具有獨立的 int 和 boolean 類型,賦值 運算符返回 int,而比較運算符返回 boolean。因而,if (x = 7) 已經成為編 譯時錯誤,就沒有必要為比較語句使用不自然的形式 if (7 == x),流暢的 Java 程序員不會這樣做。

連接字符串而非格式化字符串

多年以來,Java 語言一直沒有 printf() 函數。最終,Java 5 中增加了這 個函數,有些時候能夠發揮作用。具體來說,在您希望將數字格式化為特定寬度 或小數點後帶有特定位數的形式時,在這種不常見的情況下,格式字符串是一種 便捷的字段特定語言。而 C 程序員往往在 Java 代碼中過多地使用 printf()。 不應使用它取代簡單的字符串連接。例如:

System.out.println("There were " + numErrors + " errors  reported.");

優於:

System.out.printf("There were %d errors reported.\n",  numErrors);

變體使用了字符串連接,更易於閱讀,在簡單的情況下更是如此,此外,由 於不存在格式字符串中的占位符和數字或變量參數的類型匹配不當的情況,出現 bug 的機會也更少。

首選後增量而非前增量

在某些位置,i++ 和 ++i 之間的差別十分顯著。Java 程序員為這些位置定 義了一個具體的名稱,那就是“bug”。

不應該編寫依賴於前增量和後增量之間差異的代碼(對於 C 語言來說也是如 此)。原因在於難以理解、易於出錯。如果您發現,在您編寫的代碼中兩者的差 別有重大影響,那麼就應該重新將代碼組織為獨立的語句,使之不再能夠影響大 局。

如果前增量和後增量之間的差別不顯著 — 例如,for 循環的增量步數 — 80% 的 Java 程序員更傾向於使用後增量,只有 20% 的 Java 程序員會選擇前 增量。i++ 比 ++i 更為常用。我無法評判孰是孰非,但事實就是這樣。如果您 編寫的代碼中包含 ++i,那麼任何閱讀您的代碼的人都要浪費時間去思考您為什 麼要這樣寫。因而,除非有特殊的原因必須使用前增量(應該不存在必須使用前 增量的情況),否則請使用後增量。

錯誤處理

錯誤處理是 Java 編程中最令人困惑的問題之一,也是真正地將語言風格大 師與平凡開發者區分開來的一道門檻。實際上,僅僅錯誤處理就可以自成一篇文 章。簡而言之,合理使用異常,切勿返回錯誤代碼。

非原生語言使用者的第一類錯誤是返回一個表示錯誤的值,而不是拋出異常 。如果回溯到 Java 1.0 的年代,在 Sun 的所有程序員都充分理解了這種新語 言之前,在某些 Java 語言自己的 API 中也會看到這樣的情況。例如,考慮 java.io.File 中的 delete()方法:

public boolean delete()

若文件或目錄被成功刪除,此方法將返回 true,否則返回 false。但最合理 的做法 應該是,在成功完成時不返回任何內容,若存在出於某些原因未能刪除 的文件,則拋出異常:

public void delete() throws IOException

在方法返回錯誤值時,每一個方法調用都要包含錯誤處理代碼。在大多數正 常情況下,這使得跟蹤和理解方法的正常執行流變得困難。同時,如果由異常指 出錯誤條件,錯誤處理即可單獨作為文件末尾處的一個代碼塊。如果存在更適合 處理問題的位置,甚至可將其移動到其他方法和其他類中。

這就帶來了錯誤處理中的第二種反模式。具有 C++ 背景的程序員有時會竭力 在異常拋出後盡快處理異常。如果達到極限,可能會得到如清單 13 所示的代碼 :

清單 13. 過早的異常處理

public void readNumberFromFile(String name) {
   FileInputStream in;
   try {
     in = new FileInputStream(name);
   } catch (FileNotFoundException e) {
     System.err.println(e.getMessage());
     return;
   }

   InputStreamReader reader;
   try {
     reader = new InputStreamReader(in, "UTF-8");
   } catch (UnsupportedEncodingException e) {
     System.err.println("This can't happen!");
     return;
   }

   BufferedReader buffer = new BufferedReader(reader);
   String line;
   try {
     line = buffer.readLine();
   } catch (IOException e) {
     System.err.println(e.getMessage());
     return;
   }

   double x;
   try {
     x = Double.parseDouble(line);
   }
   catch (NumberFormatException e) {
     System.err.println(e.getMessage());
     return;
   }

   System.out.println("Read: " + x);
  }

這段代碼非常難以閱讀,甚至比異常處理取代的 if (errorCondition) 測試 更為難解。流暢的 Java 代碼將錯誤處理與故障點分離開來,不會將錯誤處理代 碼與正常執行流混合在一起。清單 14 中的版本更易於閱讀和理解:

清單 14. 保持代碼的主執行路線完好

public void readNumberFromFile(String name) {
   try {
     FileInputStream in = new FileInputStream(name);
     InputStreamReader reader = new InputStreamReader(in,  "UTF-8");
     BufferedReader buffer = new BufferedReader(reader);
     String line = buffer.readLine();
     double x = Double.parseDouble(line);
     System.out.println("Read: " + x);
   }
   catch (NumberFormatException e) {
     System.err.println("Data format error");
   }
   catch (IOException e) {
     System.err.println("Error reading from file: " +  name);
   }
  }

某些時候,您可能需要使用嵌套的 try-catch 塊來分離造成相同異常的不同 故障模式,但這種情況並不常見。主要的實踐經驗是:如果一個方法中存在多個 try 塊,那麼就表明方法過於龐大,應拆分為多個較小的方法。

最後,具有各種語言背景、剛剛接觸 Java 編程的程序員往往會錯誤地假設 他們必須在拋出檢查異常(checked exception)的方法中捕捉到這些異常。而 拋出異常的方法通常並不是應該負責捕捉異常的方法。例如,考慮如清單 15 所 示的方法:

清單 15. 過早的異常處理

public static void copy(InputStream in, OutputStream  out) {
  try {
   while (true) {
    int datum = in.read();
    if (datum == -1) break;
    out.write(datum);
   }
   out.flush();
  } catch (IOException ex) {
    System.err.println(ex.getMessage());
  }
  }

此方法沒有足夠的信息來處理很有可能發生的 IOException。它並不了解誰 調用了它,也不了解故障的後果。對於此方法來說,惟一合理的舉措就是允許 IOException 上行至調用方。編寫此方法的正確方式如清單 16 所示:

清單 16. 並非所有異常都需要在第一時間捕捉

public static void copy(InputStream in, OutputStream  out) throws IOException {
  while (true) {
   int datum = in.read();
   if (datum == -1) break;
   out.write(datum);
  }
  out.flush();
  }

簡而言之,這更為簡單、更容易理解,將錯誤信息傳遞給代碼中最適合處理 這些信息的部分。

這些問題是否真的那麼重要?

這些問題都不是關鍵問題。某些是慣例:在初次使用時聲明;在不知道如何 處理錯誤時拋出異常。其他則是純粹的風格慣例(args 而非 argv;i++ 而非 ++i)。我並不認為這些規則能使您的代碼運行速度更快,但其中一些確實能幫 助您避免 bug。如果您要成為一名流暢的 Java 語言使用者,所有這些規則都是 重要的。

無論如何,以純正的口音講話(或編寫代碼)都能使其他人更加尊重您、更 加關注您所表達的內容,甚至會為您表達的內容付給您更多的錢。此外,以純正 的口音使用 Java 語言要比說無口音的法語、漢語或英語要簡單得多。一旦您學 會了一門語言,就值得付出努力來使您的表達變得更加原汁原味。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved