JavaRush /Java Blog /Random-TW /喝咖啡休息#134。編寫 Java 程式碼時要避免什麼。Java中如何使用final、finally和finali...

喝咖啡休息#134。編寫 Java 程式碼時要避免什麼。Java中如何使用final、finally和finalize

在 Random-TW 群組發布

編寫 Java 程式碼時應避免什麼

來源:Medium 我們提醒您注意一篇文章,其中列出了開發人員在編寫 Java 程式碼時常犯的錯誤。 喝咖啡休息#134。 編寫 Java 程式碼時要避免什麼。 Java中如何使用final、finally和finalize - 1

使用 Enum.values

這被認為是一個錯誤讓我感到驚訝,因為我經常使用Enum.values。這裡的問題是Enum.values()依照規格應該是一個不可變的列表。為此,每次呼叫時都必須傳回帶有枚舉值的新數組實例。
public enum Fruits {
    APPLE, PEAR, ORANGE, BANANA;

    public static void main(String[] args) {
        System.out.println(Fruits.values());
        System.out.println(Fruits.values());
    }
}
// output
// [Lcom.test.Fruits;@7ad041f3
// [Lcom.test.Fruits;@251a69d7
這裡內存中有兩個獨立的對象,因此看起來似乎沒什麼大不了的。但是,如果您在處理請求時使用Fruit.values()並且負載很高,那麼這可能會導致記憶體問題。您可以透過引入私有靜態最終變數 VALUES 進行快取 來輕鬆解決此問題。

將可選參數作為方法參數傳遞

考慮以下程式碼:
LocalDateTime getCurrentTime(Optional<ZoneId> zoneId) {
    return zoneId.stream()
        .map(LocalDateTime::now)
        .findFirst()
        .orElse(LocalDateTime.now(ZoneId.systemDefault()));
}
我們傳遞可選參數zoneId,並根據它的存在來決定是給予系統時區的時間還是使用指定的時區。但是,這不是使用Optional 的正確方法。我們應該避免使用它們作為參數,而應使用方法重載。
LocalDateTime getCurrentTime(ZoneId zoneId) {
  return LocalDateTime.now(zoneId);
}

LocalDateTime getCurrentTime() {
  return getCurrentTime(ZoneId.systemDefault());
}
您在上面看到的程式碼更容易閱讀和調試。

使用字串產生器

Java 中的字串是不可變的。這意味著一旦創建它們就不再可編輯。JVM 維護一個字串池,在建立新字串池之前,會呼叫String.intern()方法,該方法會從字串池中傳回與該值對應的實例(如果存在)。假設我們想要透過將元素連接到其中來創建一個長字串。
String longString = new StringBuilder()
  .append("start")
  .append("middle")
  .append("middle")
  .append("middle")
  .append("end")
  .toString();
最近我們被告知這是一個非常糟糕的主意,因為舊版本的 Java 執行了以下操作:
  • 在第 1 行,字串「start」被插入字串池並由longString指向
  • 第 2 行將字串「startmiddle」加入到池中,並用longString指向它
  • 在第 3 行我們有“startmiddlemiddle”
  • 第 4 行 - “startmiddlemiddlemiddle”
  • 最後在第 5 行,我們將“startmiddlemiddlemiddleend”添加到池中並將longString指向它
所有這些行都保留在池中並且從未使用過,導致大量 RAM 被浪費。為了避免這種情況,我們可以使用 StringBuilder。
String longString = new StringBuilder()
  .append("start")
  .append("middle")
  .append("middle")
  .append("middle")
  .append("end")
  .toString();
當呼叫toString方法 時,StringBuilder 僅建立一個字串,從而擺脫最初添加到池中的所有中間字串。但是,在 Java 5 之後,這是由編譯器自動完成的,因此最好使用“+”進行字串連接。

在不需要時使用原始包裝器

考慮以下兩個片段:
int sum = 0;
for (int i = 0; i < 1000 * 1000; i++) {
  sum += i;
}
System.out.println(sum);
Integer sum = 0;
for (int i = 0; i < 1000 * 1000; i++) {
  sum += i;
}
System.out.println(sum);
在我的電腦上,第一個範例的運行速度比第二個範例快六倍。唯一的區別是我們使用 Integer 包裝類別。Integer 的工作方式是,在第 3 行,執行階段必須將 sum 變數轉換為原始整數(自動拆箱),加法完成後,將結果包裝到新的 Integer 類別中。(自動包裝)。這意味著我們正在創建 100 萬個 Integer 類別並執行 200 萬個打包操作,這解釋了速度急劇下降的原因。僅當需要將包裝類別儲存在集合中時才應使用包裝類別。然而,Java 的未來版本將支援原始類型的集合,這將使包裝器過時。

Java中如何使用final、finally和finalize

資料來源:Newsshare 在本文中,您將了解 Finalize 關鍵字的使用地點、時間和原因,以及它是否值得在 Java 中使用。您還將了解 Final、finally 和 Finalize 之間的差異。

哪裡使用了finally區塊?

Java 中的finally 區塊用於容納程式碼的重要部分,例如清理程式碼、關閉檔案或關閉連線。無論是否引發異常或是否處理該異常,finally 區塊都會執行。無論是否發生異常,finally 都包含所有重要的語句。

Java 中如何終結變數?

Java 變數的初始化有 3 種方法:
  • 您可以在聲明最終變數時對其進行初始化。這種方法是最常見的。
  • 空的最終變數在實例初始化區塊或建構函數中初始化。
  • 空的最終靜態變數在靜態區塊內初始化。

我們可以在Java中手動呼叫finalize方法嗎?

Finalize()方法不是必需的,也不建議在物件超出範圍時呼叫。因為事先並不知道finalize()方法何時(或是否)會被執行。一般來說,除非有特殊需要,否則 Finalize 並不是最好的方法。從 Java 9 開始,它已被棄用。

Finalize方法什麼時候被呼叫?

Finalize()方法在垃圾回收之前被呼叫以執行清理。

Final、finally 和 Finalize 和有什麼不一樣?

Final、finally 和 Finalize 之間的主要區別在於,final 是存取修飾符,finally 是異常處理中的區塊,而 Finalize 是物件類別的方法。

是否可以重寫final方法?

不可以,宣告為 Final 的方法不能被覆寫或隱藏。

我們可以使用 try 而不使用 catch 嗎?

是的,透過使用Final區塊,可以有一個沒有catch區塊的try區塊。我們知道,即使try區塊中發生了System以外的異常,finally區塊總是會被執行。

什麼是最終方法?

Final 方法不能被子類別覆蓋或隱藏。它們用於防止子類別修改對類別的功能或一致性可能至關重要的方法的意外行為。

構造函數可以是最終的嗎?

構造函數永遠不能被宣告為最終的。你的編譯器總是會拋出一個錯誤,例如「不允許使用final修飾符」。Final 當應用於方法時表示該方法不能在子類別中被重寫。構造函數不是常規方法。

finally 關鍵字有什麼用?

finally 關鍵字用於在 try 區塊後面建立一個程式碼區塊。無論是否發生異常,finally 區塊都會被執行。使用finally 區塊可讓您執行您想要執行的任何展開類型語句,而不管受保護的程式碼中發生了什麼。

最後有什麼用?

Java 中的finally 區塊是用來執行部分程式碼(例如關閉連線等)的區塊。Java中的finally區塊無論異常是否被處理都會被執行。因此,它包含了無論是否發生異常都需要列印的所有必要語句。

為什麼 Finalize 方法受到保護?

為什麼Finalize()方法存取修飾符受到保護?為什麼不能公開呢?它不是公開的,因為它不應該被 JVM 以外的任何人呼叫。但是,它必須受到保護,以便可以被需要為其定義行為的子類別覆寫。

Java中是否總是呼叫finalize方法?

當物件即將被垃圾回收時,將呼叫 Finalize 方法。這可能在它符合垃圾回收條件後的任何時間發生。請注意,該物件完全有可能永遠不會被垃圾回收(因此永遠不會呼叫 Finalize)。

投擲和投擲有什麼區別?

throw 關鍵字用於有意拋出例外。throws 關鍵字用於聲明一個或多個異常,並以逗號分隔。使用 throw 時,僅拋出一個例外。

try catch 和finally 關鍵字有什麼不同?

這是兩個不同的概念:只有當 try 區塊中發生異常時,才會執行 catch 區塊。無論是否拋出異常,finally 區塊總是會在 try(-catch) 區塊之後執行。

在Java中我們可以不用try直接使用finally嗎?

finally 區塊必須與 try 區塊關聯,如果沒有 try 區塊,則不能使用finally。您必須將那些必須始終執行的語句放置在此區塊中。

我們可以繼承final方法嗎?

最終方法是繼承的嗎?是的,final 方法是繼承的,但你不能覆寫它。

哪個方法不能被覆蓋?

我們不能重寫靜態方法,因為方法重寫是基於運行時的動態鏈接,而靜態方法是在編譯時使用靜態鏈接綁定的。因此,重寫靜態方法是不可能的。

如果最終方法被重寫會發生什麼?

父類別中宣告的final方法不能被子類別覆蓋。如果我們嘗試重寫最後一個方法,編譯器將在編譯時拋出異常。

Final關鍵字和finalize方法的作用相同嗎?

除了名稱相似外,它們的功能沒有相似之處。Final關鍵字可以與Java中的類別、方法或變數一起使用。在 Java 中,final 類別不可擴展,final 方法不能被覆寫,final 變數也不能被修改。

Java中的super關鍵字是什麼?

Java中的super關鍵字是一個引用變量,用於引用父類別的直接物件。每當實例化子類別時,都會並行建立父類別的實例,該實例由引用變數 super 引用。super關鍵字可以用來直接呼叫父類別的方法。

static 和final 關鍵字有什麼不同?

static 和final 關鍵字之間的主要區別在於,static 關鍵字用於定義類別的成員,該成員可以獨立於該類別的任何物件使用。Final關鍵字用於宣告常數變數、不可重寫的方法和不可繼承的類別。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION