【java】String创建对象的两种方式

在 Java 中,创建 String 对象有两种主要方式:


1. 使用双引号直接创建(推荐)

  • 这是最常见的方式,直接使用双引号 " " 创建字符串。

  • 这种方式的字符串会被放入 字符串常量池(String Pool),如果常量池中已经存在相同内容的字符串,则会复用该对象,而不会创建新的对象。

  • 优点:节省内存,提高性能。

语法:

java

String str = "Hello";
示例:

java

String s1 = "Hello"; // 创建字符串并放入常量池
String s2 = "Hello"; // 复用常量池中的 "Hello" 对象

System.out.println(s1 == s2); // true,因为 s1 和 s2 指向同一个对象

2. 使用 new 关键字创建

  • 通过 new 关键字创建字符串对象时,每次都会在堆内存中创建一个新的对象,即使内容相同。

  • 这种方式创建的字符串不会放入字符串常量池,除非显式调用 intern() 方法。

语法:

java

String str = new String("Hello");
示例:

java

String s1 = new String("Hello"); // 在堆内存中创建一个新对象
String s2 = new String("Hello"); // 在堆内存中创建另一个新对象

System.out.println(s1 == s2); // false,因为 s1 和 s2 是不同的对象
System.out.println(s1.equals(s2)); // true,因为内容相同

3. 两种方式的区别

特性双引号直接创建new 关键字创建
对象存储位置字符串常量池(String Pool)堆内存(Heap)
是否复用对象是(如果常量池中已存在相同内容)否(每次都会创建新对象)
性能更高(复用对象,节省内存)较低(每次创建新对象)
适用场景推荐使用,尤其是内容固定的字符串需要显式创建新对象时使用

4. 字符串常量池(String Pool)

  • 字符串常量池是 Java 中为了节省内存而设计的一种机制。

  • 当使用双引号创建字符串时,Java 会先检查常量池中是否存在相同内容的字符串:

    • 如果存在,则直接复用该对象。

    • 如果不存在,则在常量池中创建一个新对象。

示例:

java

String s1 = "Hello"; // 创建并放入常量池
String s2 = "Hello"; // 复用常量池中的对象
String s3 = new String("Hello"); // 在堆内存中创建新对象

System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false

5. intern() 方法

  • intern() 方法可以将 new 创建的字符串对象放入字符串常量池(如果池中不存在相同内容)。

  • 如果池中已存在相同内容,则返回池中的对象。

示例:

java

String s1 = new String("Hello"); // 在堆内存中创建新对象
String s2 = s1.intern(); // 将 s1 的内容放入常量池(如果不存在)
String s3 = "Hello"; // 复用常量池中的对象

System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // true

6. 完整代码示例

java

public class Main {
    public static void main(String[] args) {
        // 方式 1:双引号直接创建
        String s1 = "Hello";
        String s2 = "Hello";

        // 方式 2:new 关键字创建
        String s3 = new String("Hello");
        String s4 = new String("Hello");

        // 比较引用
        System.out.println("s1 == s2: " + (s1 == s2)); // true
        System.out.println("s1 == s3: " + (s1 == s3)); // false
        System.out.println("s3 == s4: " + (s3 == s4)); // false

        // 比较内容
        System.out.println("s1.equals(s3): " + s1.equals(s3)); // true

        // 使用 intern() 方法
        String s5 = s3.intern();
        System.out.println("s1 == s5: " + (s1 == s5)); // true
    }
}

7. 总结

  • 双引号直接创建:推荐使用,性能高,适合内容固定的字符串。

  • new 关键字创建:适合需要显式创建新对象的场景。

  • 字符串常量池:通过双引号创建的字符串会放入常量池,复用对象以节省内存。

  • intern() 方法:可以将 new 创建的字符串放入常量池。

 

将字符串放入字符串常量池的意义:

将字符串放入字符串常量池(String Pool)是 Java 为了优化内存和提高性能而设计的一种机制。它的意义主要体现在以下几个方面:


1. 节省内存

  • 字符串常量池是一个特殊的内存区域,用于存储字符串字面量(即用双引号直接创建的字符串)。

  • 当多个字符串变量具有相同的内容时,它们可以共享常量池中的同一个对象,而不是在内存中创建多个重复的对象。

  • 这样可以显著减少内存占用,尤其是在处理大量相同内容的字符串时。

示例:

java

String s1 = "Hello"; // 创建并放入常量池
String s2 = "Hello"; // 复用常量池中的对象

System.out.println(s1 == s2); // true,s1 和 s2 指向同一个对象

在这个例子中,s1 和 s2 共享常量池中的同一个 "Hello" 对象,而不是创建两个独立的对象。


2. 提高性能

  • 由于字符串常量池中的对象可以被复用,减少了对象的创建和销毁次数,从而降低了垃圾回收(Garbage Collection)的压力。

  • 字符串的比较操作(如 equals() 或 ==)也会更快,因为如果两个字符串引用指向常量池中的同一个对象,可以直接判断它们相等,而不需要逐个字符比较。

示例:

java

String s1 = "Hello";
String s2 = "Hello";

// 使用 == 比较,直接判断引用是否相同
System.out.println(s1 == s2); // true

3. 避免重复创建

  • 在 Java 中,字符串是不可变的(immutable),即一旦创建,内容就不能被修改。

  • 如果每次都需要创建新的字符串对象,会导致大量重复的对象占用内存。

  • 通过字符串常量池,可以避免重复创建相同内容的字符串对象。

示例:

java

for (int i = 0; i < 1000; i++) {
    String s = "Hello"; // 复用常量池中的对象,而不是创建 1000 个新对象
}

4. intern() 方法的作用

  • 对于通过 new 关键字创建的字符串,它们不会自动放入常量池。

  • 如果希望将这些字符串放入常量池以复用,可以调用 intern() 方法。

  • intern() 方法会检查常量池中是否存在相同内容的字符串:

    • 如果存在,则返回常量池中的对象。

    • 如果不存在,则将当前字符串放入常量池并返回。

示例:

java

String s1 = new String("Hello"); // 在堆内存中创建新对象
String s2 = s1.intern(); // 将 s1 的内容放入常量池(如果不存在)
String s3 = "Hello"; // 复用常量池中的对象

System.out.println(s1 == s2); // false
System.out.println(s2 == s3); // true

5. 适用场景

  • 适合放入常量池的字符串

    • 内容固定的字符串(如常量、配置项、枚举值等)。

    • 频繁使用的字符串(如日志消息、错误提示等)。

  • 不适合放入常量池的字符串

    • 动态生成的字符串(如用户输入、随机字符串等)。

    • 生命周期较短的字符串(如临时变量)。


6. 总结

将字符串放入常量池的主要意义在于:

  1. 节省内存:通过复用对象,减少重复字符串的内存占用。

  2. 提高性能:减少对象创建和垃圾回收的开销,加快字符串比较速度。

  3. 避免重复创建:对于内容相同的字符串,复用常量池中的对象。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值