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