簡體   English   中英

為什么String.length()是一個方法?

[英]Why is String.length() a method?

如果一個String對象是不可變的(因此顯然不能改變它的長度),為什么length()是一個方法,而不是簡單地成為public final int length例如在數組中?

它只是一個getter方法,還是進行某種計算?

試着看看這背后的邏輯。

Java是一種標准,而不僅僅是一種實現。 不同的供應商可以以不同的方式許可和實施Java,只要它們符合標准即可。 通過對字段進行標准調用,可以非常嚴重地限制實現,這是沒有充分理由的。

對於課程的未來而言,方法也更靈活。 除了在一些非常早期的Java類中,幾乎從未完成將最終常量公開為一個字段,該字段可以與類的每個實例具有不同的值,而不是作為方法。

length()方法早於 CharSequence接口,可能是它的第一個版本。 看看效果如何。 多年以后,沒有任何向后兼容性的損失,CharSequence接口被引入並且非常適合。 對於一個領域來說這是不可能的。

所以,讓我們真正顛倒這個問題(當你設計一個幾十年來保持不變的類時,你應該做什么):這里有什么領域,為什么不簡單地把它作為一個方法呢?

也許.length()方法被認為與StringBuffer的相應方法更加一致,這顯然需要多於final成員變量。

String類可能是為Java定義的最早的類之一。 有可能(這只是推測)實現在final成員變量存在之前使用了.length()方法。 在將該方法的使用很好地嵌入到當時存在的Java代碼體中之前,不需要很長時間。

也許是因為length()來自CharSequence接口 如果一個方法有多個實現,那么它是一個比變量更合理的抽象。

這是封裝的基本原則。

封裝的一部分是類應該從其接口隱藏其實現(在“按合同設計”的接口意義上,而不是在Java關鍵字意義上)。

你想要的是String的長度 - 你不應該關心它是否被緩存,計算,委托給其他領域等等。如果JDK人員希望改變實施方式,他們應該能夠這樣做你必須重新編譯。

您應該始終在公共類而不是公共字段中使用訪問器方法,無論它們是否為final(請參閱Effective Java中的第14項)。

當您允許直接訪問字段(即公開)時,您將失去封裝的好處,這意味着您無法在不更改API的情況下更改表示(如果您這樣做,則會破壞人員代碼)並且您無法執行任何操作訪問該字段時的操作。

有效的Java提供了一個非常好的經驗法則:

如果類可以在其包外部訪問,則提供訪問器方法,以保持更改類的內部表示的靈活性。 如果公共類公開其數據字段,則所有更改其表示的希望都將丟失,因為客戶端代碼可以遠程分發。

基本上,它是這樣做的,因為這樣做是很好的設計實踐。 它留有空間在稍后階段更改String的實現,而不會破壞每個人的代碼。

String使用封裝來隱藏其內部細節。 只要外部可見狀態不變,不可變對象仍然可以自由地具有可變內部值。 長度可以懶惰計算。 我鼓勵你看一下String的源代碼。

Open JDK中檢查String的源代碼,它只是一個getter。

但正如@SteveKuo指出的那樣,這可能因實施而異。

在大多數當前的jvm實現中,Substring引用內容的原始String的char數組,它需要start和length字段來定義自己的內容,因此length()方法用作getter。 但是,這不是實現String的唯一可能方法。

在一個不同的可能實現中,每個String都可以有自己的char數組,因為char數組已經有一個長度正確的長度字段,所以String對象有一個冗余字段,因為String.length()是我們不知道的方法。必須這樣做,只能引用內部array.length。

這是String的兩種可能實現,它們都有自己的好的和壞的部分,並且它們可以互相替換,因為length()方法隱藏了存儲長度的位置(內部數組或在自己的字段中)。

暫無
暫無

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

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