没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码:
String s = "Hello";
s = s + " world!";
s 所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:
public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
而非
s = new String("Initial Value");
后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。
上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。
分享到:
相关推荐
第二种形式是先在栈中创建一个对 String 类的对象引用变量 str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令 str 指向"abc",如果已经有"abc",则直接令 str 指向"abc"。 那么,为什么 String...
String类的字符串是不可变的,即使你对其进行了添加、删除等操作,也是从内存的其他区域进行存储的,而不是在原来的字符串上进行修改。这是因为String类使用了final关键字,使得它的字符串内容不能被修改。 在...
然而,对于大型项目或涉及多语言的应用,管理`String.xml`文件可能会变得复杂。Excel表格提供了一个更直观的方式来编辑和管理这些字符串,尤其是当有多个团队成员协作或者需要进行多语言本地化时。Excel可以轻松地...
1. 可变性:`String`不可变,`StringBuffer`(和`StringBuilder`)可变。 2. 性能:频繁修改字符串时,`StringBuffer`(或`StringBuilder`)性能优于`String`。 3. 线程安全:`StringBuffer`是线程安全的,`...
在Eclipse IDE中,虽然没有内置的转换功能,但可以借助外部插件或独立工具完成这一过程。对于Eclipse用户,可以搜索相关的插件集成到开发环境中,或者单独使用命令行工具配合版本控制系统(如Git)来管理和同步`...
而`std::string`内部维护了一个可变长度的字符数组,这要求在创建时进行适当的初始化,以确保正确地分配和管理内存。 在给出的示例代码中: ```cpp temp *q; q=(struct temp*)malloc(sizeof(struct temp)); q->s=p...
字符串在Java中被视为不可变对象,这意味着一旦创建了一个`String`对象,就不能更改它的值。下面我们将深入探讨`String`类的一些关键知识点,以及如何通过练习来熟练掌握它们。 1. **创建String对象**: - 字面量...
3. **`length()`与`size()`**:在Java中,`String`类提供了`length()`方法来获取字符串的字符数,但并没有提供`size()`方法。`length()`返回的是字符串中字符的数量,不包括结束的空字符`\0`。 4. **`charAt(int ...
`String`类是不可变的,这意味着一旦创建了一个`String`对象,它的内容就不能被修改。每次对`String`对象进行操作(如拼接、替换字符等),都会创建一个新的`String`对象。这种特性使得`String`在多线程环境下更...
`StringBuilder`是Java 5.0新增的类,它是非线程安全的,这意味着在单线程环境下,StringBuilder的性能通常优于StringBuffer,因为它没有进行额外的同步操作。在需要多次修改字符串内容时,StringBuilder是个不错的...
- **String**:适用于不需要修改且对线程安全没有特殊要求的场景。 - **StringBuffer**:适用于需要修改字符串内容且对线程安全有要求的场景。 - **StringBuilder**:适用于不需要修改字符串内容且对性能有较高要求...
当程序员没有正确提供格式字符串(format string)或允许用户控制格式字符串时,攻击者可以利用此漏洞来改变程序执行流程,获取敏感信息,甚至执行任意代码。 漏洞产生的原因是,`printf`系列函数会解析格式字符串...
在Java语言中,`String`类是用于表示不可变字符序列的核心类之一。它代表了一个字符串对象,一旦被初始化后,其内容不能被改变。这被称为不可变性(Immutability),是Java编程语言的一个关键特性。 **创建String...
本文主要来介绍一下Java中的不可变对象,以及Java中String类的不可变性,那么为什么Java的String类是不可变对象?让我们一起来分析一下。 答案一: 流行的Java面试题之一是:什么是不可变对象(immutable ...
Java中的String类是编程中非常基础且重要的一个类,它代表不可变的字符序列,即一旦创建,其内容就不能更改。下面我们将详细讨论String类的一些主要特性、实例化方式以及常用方法。 1. **String类的实例创建**: -...
此外,astring库生成的代码格式简洁,没有额外的缩进或空格,这在某些场景下是理想的,特别是当代码需要被其他工具进一步处理时。 在实际项目中,astring可以与其他前端工具链组件结合使用。比如,配合Babel进行...
- `String`类是不可变的,意味着一旦创建,其内容就不能改变。每次对`String`对象进行修改(如连接、替换字符等),都会生成一个新的`String`对象。这是因为`String`对象存在于常量池中,修改操作实际上是在常量池...
而String通常用于表示不可变的、简单的字符串值,或者在常量池中的字符串表达式。在进行字符串拼接时,特别是循环或递归操作中,避免使用String的`+`操作符,因为它会频繁创建新对象,而应优先考虑使用StringBuffer...