当前位置: 首页 > java >正文

32.String str=aaa与 String str=new String(aaa)一样吗?new String(“aaa”);创建了几个字符串对象

32.String str="aaa"与 String str=new String(“aaa”)一样吗?new String(“aaa”);创建了几个字符串对象?

  • String str = “aaa” 会先在字符串常量池里寻找有没有这个字符串,如果没有,就会在常量池里新建一个对象,然后把对象地址赋给str。

  • String str=new String(“aaa”) 是会在堆中创建一个存储空间,然后去常量池里寻找有没有这个字符串,如果没有就会再新建一个对象,然后再把对象的地址赋给这个字符串。相当于创建了两个对象

String str = "aaa"String str = new String("aaa") 不完全相同,它们在内存分配和对象引用上存在关键区别。以下是详细分析:


1. 内存分配的区别

String str = "aaa"
  • 创建对象数1个对象
  • 机制:Java 的字符串常量池(String Pool)会缓存所有字面量字符串(如"aaa")。当使用String str = "aaa"时:
    1. JVM 会先检查常量池中是否已存在值为 "aaa" 的字符串对象。
    2. 如果存在,直接返回该对象的引用(str 指向常量池中的对象)。
    3. 如果不存在,JVM 会在常量池中创建 "aaa" 并返回引用。
String str = new String("aaa")
  • 创建对象数2个对象
  • 机制:
    1. 常量池中的对象:如果常量池中没有 "aaa",JVM 会先创建它(同上)。
    2. 堆内存中的对象new String("aaa") 会通过构造函数在堆内存中显式创建一个新的字符串对象,内容与常量池中的 "aaa" 相同。
    3. 最终,str 引用的是堆中的对象,而不是常量池中的对象。

2. 对象引用的区别

  • String str = "aaa"

    • str 指向常量池中的对象。

    • 示例:

      String s1 = "aaa";
      String s2 = "aaa";
      System.out.println(s1 == s2); // true(引用同一个常量池对象)
      

String str = new String("aaa")

  • str 指向堆中的对象。

  • 示例:

    String s1 = new String("aaa");
    String s2 = new String("aaa");
    System.out.println(s1 == s2); // false(堆中是两个不同对象)
    System.out.println(s1.equals(s2)); // true(内容相同)
    

3. new String("aaa") 创建了几个对象?

  • 答案:2个对象。
    1. 常量池中的对象"aaa"(如果之前未创建过)。
    2. 堆内存中的对象:通过 new String("aaa") 显式创建的新对象。

4. 为什么推荐使用字符串字面量?

  • 性能优势:
    • 字符串常量池可以复用相同值的对象,减少内存开销。
    • 使用 new String("aaa") 会导致堆中冗余对象,增加 GC 压力。
  • 线程安全:
    • 常量池中的字符串是不可变的(immutable),天然线程安全。
    • new String("aaa") 创建的对象虽然是不可变的,但多线程环境下仍需注意引用一致性。

5. 特殊场景下使用 new String()

  • 需要独立对象
    当需要确保字符串对象具有独立身份(如基于引用的比较 ==)时。
  • 安全考虑
    处理不可信数据时,避免共享敏感信息(如密码)。
  • 框架需求
    某些框架(如 Hibernate)可能依赖对象引用的唯一性。

总结

特性String str = "aaa"String str = new String("aaa")
对象数1(常量池)2(常量池 + 堆)
引用对象常量池对象堆中的新对象
== 比较结果同值对象引用相同同值对象引用不同
推荐使用场景通用场景特殊需求(独立对象、安全等)

如果不需要特殊需求,优先使用字符串字面量String str = "aaa")以优化性能和内存。

String 是最基本的数据类型吗

不是,String是引用数据类型。Java里有8个基本数据类型 byte, short, int, long, float, double, char, blooean。

String 有什么特性

  • 不可变性

    • 对一个String字符串进行任何的修改都是会新建一个对象,再把引用指向该对象,原的字符串是不会做任何改变。在多线程共享访问时,可以保证数据一致性。

    • 定义:一旦创建,String 对象的内容和长度无法被修改。

    • 实现机制:

      • String 的底层通过 final char[] value 存储字符数据,且 value 被声明为 final,禁止外部修改。
      • 所有修改操作(如拼接、替换)都会生成新的 String 对象,原对象保持不变。
    • 示例

      String s = "Hello";
      s = s + " World"; // 创建新对象 "Hello World",s 指向新对象,原 "Hello" 未被修改
      
  • 常量池优化

    • String 创建之后,会先在字符串常量池里寻找,如果没有,就会新建一个,如果有,就会把常量池的对象的引用拿出来。提高了性能和减少了内存的开销

    • 机制:

      • 使用字面量(如String s = “abc”)创建时,JVM 会检查常量池是否存在相同值的对象:
        • 存在:直接返回池中对象的引用。
        • 不存在:创建新对象并放入池中。
      • 使用 new String(“abc”)时:
        • 先检查常量池是否存在 "abc"(若无则创建),再在堆中创建新对象。
    • 示例

      String s1 = "abc";          // 池中对象
      String s2 = "abc";          // s1 == s2 → true
      String s3 = new String("abc"); // 堆中新对象
      System.out.println(s1 == s3); // false
      
  • final 修饰:String 底层还是用数组来实现的,用final来修饰的。

在使用 HashMap 的时候,用 String 做 key 有什么好处?

HashMap会先计算hashCode值,如果是String的话,因为String不可变,String也会去常量池缓存,这样就不会每一次都要计算hashCode值。而是先去在常量池里去匹配,没有再去创建。

http://www.xdnf.cn/news/19135.html

相关文章:

  • Linux按键驱动开发
  • 明远智睿 RK3568 核心板:以硬核性能解锁多领域应用新可能
  • 手写一个Spring框架
  • 【活动回顾】“智驱未来,智领安全” AI+汽车质量与安全论坛
  • Labview邪修01:贪吃蛇
  • 数据结构:归并排序 (Iterative Merge Sort)
  • 非支配排序遗传算法进化多目标优化算法
  • 【混合开发】Android+webview模拟crash崩溃补充说明
  • 【LeetCode每日一题】141. 环形链表 142.环形链表 II
  • Rspack
  • Kafka入门指南:从安装到集群部署
  • Mock 在 API 研发中的痛点、价值与进化及Apipost解决方案最佳实践
  • 【Docker/Redis】服务端高并发分布式结构演进之路
  • RS485、RS232、RS422协议
  • 若依微服务一键部署(RuoYi-Cloud):Nacos/Redis/MySQL + Gateway + Robot 接入(踩坑与修复全记录)
  • 云手机的安全性如何?
  • LeetCode Hot 100 第8天
  • 群组分析 (Cohort Analysis)——哪批用户最优质?
  • 【Spring底层分析】Spring AOP补充以及@Transactional注解的底层原理分析
  • 12大主流本地文档管理系统功能与价格对比分析
  • 如何设置阿里云轻量应用服务器镜像?
  • v-model与v-bind区别
  • LG P5386 [Cnoi2019] 数字游戏 Solution
  • CesiumJS 介绍以及基础使用
  • 【完整源码+数据集+部署教程】硬币分类与识别系统源码和数据集:改进yolo11-SWC
  • GoogLeNet:深度学习中的“卷积网络变形金刚“
  • 从“安全诉讼”说起:奖励模型(Reward Model)是LLM对齐的总阀门(全视角分析)
  • 如何在实际应用中选择Blaze或Apache Gluten?
  • 【拍摄学习记录】06-构图、取景
  • 表复制某些字段的操作sql