簡體   English   中英

我是否需要為 Java 中的所有不可變變量指定 «final» 修飾符?

[英]Do I need to specify «final» modifier for ALL immutable variables in Java?

在我讀過的一本 Java 書中, “一般來說,如果不需要重新分配變量,則始終將變量聲明為 final,將常量字段聲明為 static final 是個好主意” 我開始遵循這個建議。 但是當我開始編碼時,我發現幾乎所有的變量都是不可變的。 但是使用關鍵字«final»會使行變得更長,因此更難閱讀代碼,這違背了干凈代碼的原則。 所以這里是我的問題:

  1. 將所有不可變變量設為“final”是一個好習慣嗎?
  2. 您是否對程序中的所有不可變變量使用 «final» 修飾符?
  3. 如果沒有,你什么時候使用«final»,什么時候跳過使用這個關鍵字?

這是我的代碼教練存儲庫中的程序示例。 所有變量都是最終的。 同樣的情況幾乎出現在存儲庫中的所有其他程序中。

import java.util.Scanner;

public class NoNumerals
{
    public static void main(String[] args) {
        final var input = new Scanner(System.in);
        final var phrase = input.nextLine();
        final String[] numbers = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};
        final var updatedPhrase = new StringBuilder();

        for (final var word : phrase.split(" ")) {
            try {
                final int number = Integer.parseInt(word);
                if (number >= 0 && number <= 10) {
                    updatedPhrase.append(numbers[number]);
                } else {
                    updatedPhrase.append(word);
                }
            } catch (NumberFormatException nfe) {
                updatedPhrase.append(word);
            }
            updatedPhrase.append(" ");
        }
        System.out.print(updatedPhrase);
    }
}

您可能想要聲明變量final原因有多種,包括:

  • 簡單性- 必須初始化最終變量,並且不能重新分配。 因此,一段代碼使讀者不必對可變狀態或未初始化的變量進行推理。 編譯器將阻止兩者。 這意味着 final 變量還將防止錯誤,例如意外重新分配或意外使用未初始化的類成員。

  • 自記錄- 聲明為 final 的變量或類成員是向用戶明確表示永遠不應重新分配變量的意圖的信號。

  • 線程安全- 無需同步即可安全讀取最終引用。 一個不可變對象(即所有成員字段都是最終的,並且可以是原始對象或對其他不可變對象的引用),可以在沒有同步的情況下並發訪問。

  • 編譯器所需的用例- 只有有效的最終變量才能在 try-with-resources 表達式中引用,或由 lambdas 捕獲。 有關 beeween final有效 final隱式 final變量之間差異的概述,請參閱以下此答案

順便說一句,我注意到有使用“純函數”語言(例如 F# 和 Haskell)經驗的開發人員傾向於自由使用final 在這些語言中,所有值都是“默認不可變的”。 在使用這些語言后回到 Java 時,我發現自己缺少“默認不可變”方法提供的簡單性和自由度。

將所有不可變變量設為final是好習慣嗎?

我推薦以下實踐,這些實踐在過去十年中對我作為一名專業開發人員很有幫助:

  • 默認情況下,類成員應聲明為final 只有在我們明確想讓它們可變的情況下,才應該將成員聲明為非最終的。
  • 方法中的變量應該被聲明為 final,其中提供的值(在簡單性和正確性保證方面)超過任何諸如混亂之類的問題。 對於變量很少的簡短方法,好處是微乎其微的。 對於有很多變量的長方法,好處會更大。

由於可變狀態的復雜使用,最終方法變量的使用還可以防止某些難以推理的編碼模式。 可變狀態有時是必要的,但通常不是。

作為練習,嘗試在一天內默認將所有方法變量聲明為 final,以了解支持這種方法所需的模式和實踐。

這里沒有通用的最佳實踐。 在上述好處和簡潔性之間需要進行權衡(有些人認為final關鍵字會增加混亂,但我並不傾向於同意)。 final 的使用也可能取決於與其他編碼實踐的兼容性(例如,有些人喜歡使用默認構造函數,然后使用 setter 來填充字段,我認為這不是一個好的做法)。

許多“總是final ,除非有理由不這樣做”方法的支持者 也有許多人主張更謹慎地使用 final,包括Clean Code 中的Bob Martin。 Google Java Style Guide對這個問題特別沉默。

我不同意對final自由使用違背干凈代碼的原則,它重視簡單性和自我記錄代碼。

您是否對程序中的所有不可變變量使用final修飾符?

如上所述,一般來說:

  • 班級成員 - 是的,對於給定的班級成員,除非有理由不這樣做,否則是final
  • 方法變量 - 並非總是如此,但通常用於非平凡的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM