1.比較
程序員需要一直比較不同的變量。但是,正如您已經看到的,一切都不是那麼簡單。
整數非常容易比較——你只需使用==
就可以了。要比較實數,您必須將它們的差異(或者更確切地說,差異的絕對值)與一些非常小的數字進行比較。
比較字符串更加困難。最重要的是,這是因為字符串是對象。更重要的是,程序員通常希望字符串比較根據情況有所不同。
2.字符串是如何排列內存的
正如您已經看到的,字符串在內存中的存儲方式不同於整數和實數:
兩個內存塊用於存儲字符串:一個塊存儲文本本身(其大小取決於文本的大小),而第二個塊(4 個字節)存儲第一個塊的地址。
儘管有經驗的程序員會說類似“String
str
變量存儲對對象的引用String
。
3. 分配對字符串的引用
當您需要將一個字符串變量分配給另一個字符串變量時,這種方法的好處就很明顯了。例子:
String text = "This is a very important message";
String message = text;
結果是內存將包含的內容:
在這種類型的賦值操作之後,String
對象保持在原來的位置,只是它的地址(對對象的引用)被複製到變量中message
。
4. 使用引用和對象
但是,如果您決定將字符串轉換為大寫(大寫字母),Java 機器會做所有正確的事情:您最終會得到兩個String
對象,並且text
變量message
將存儲引用,每個對像都指向自己的對象。
例子:
String text = "This is a very important message";
String message = text.toUpperCase();
結果是內存將包含的內容:
請注意,該toUpperCase()
方法不會更改調用它的字符串。相反,它創建一個新字符串(新對象)並返回對它的引用。
舉一個更有趣的例子怎麼樣。假設您決定將一個字符串傳遞給一個Scanner
對象(以便它從該字符串中讀取值)。
例子:
String text = "10 20 40 80";
Scanner console = new Scanner(text);
int a = console.nextInt();
int b = console.nextInt();
您可以在此處詳細了解該Scanner
課程的運作方式。
這就是它將全部存儲在內存中的方式:
在這種情況下,單個String
對象保留在內存中,就像它原來一樣——只有對它的引用被傳遞並存儲在變量中。
5.比較對String
對象的引用
最後,我們到了有趣的部分:字符串比較。
有兩個運算符可用於比較字符串變量:(==
等於)和!=
(不等於)。您不能使用“大於”、“小於”或“大於或等於”運算符——編譯器不允許。
但是這裡有一個有趣的細微差別:實際上存儲在字符串變量中的是什麼?沒錯:對象的地址(引用)。將比較這些地址:
String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();
這是內存中的內容:
和message
變量text
引用(存儲地址)同一個對象。但是s1
和s2
變量存儲對非常相似但不同的對象的引用。
如果你在代碼中比較這 4 個變量,那麼你會得到以下結果:
代碼 | 控制台輸出 |
---|---|
|
|
GO TO FULL VERSION