首先我并不知道在常量池中存放的是引用还是对象,先不管它,我觉得是保存的对象,只是猜测。
在使用中String str=?;的方式来创建一个字符串对象时,虚拟机首先会对?所代表的字符串进行检查,在字符串常量池中是否有对应的字符串,如果有则将str指向该字符串对象,如果没有则会创建一个新的字符串对象并将其引用返回;
而使用String str1=new String(?);来创建时,这种方式并不会去检查字符串常量池,而是直接在堆中new一个新的String对象,值为?所代表的字符串,new出来的对象。
为什么java中会有两种方式的String呢?
因为String是一个类,只要创建一个字符串就是一个实例,就是相同的字符串也会新建一个新的对象,如果全部存在堆中则会消耗大量的内存来保存字符串(可能还不会被GC系统进行回收),所以java就运用字符串常量池来保存建立的String对象,通过虚拟机的一些运算(其实是调用在String中已经被重写的equals()方法)来判断字符串常量池中是否有相同的字符串如果有,就返回已经存在的字符串的引用;如果没有,那就在字符串常量池中新建一个字符串对象并返回它的引用。这种方式来创建字符串的话,占用的内存空间较少,并且有很高的复用性,但是牺牲了虚拟机的运算时间,算是一种时间换取空间的做法。
所以这也是为什么 String str4="java";String str5="java";str4==str5会返回true的原因;还有就是String str6="ja"+"va";str5==str6;也会返回true,那是因为在编译时期,编译器会创建一个StringBuilder,并用append()方法来将这些字符串拼接起来,最后再将StringBuilder的对象的字符串添加到字符串常量池中,并返回引用给str6;
那么如何将堆中new出来的字符串对象加入到字符串常量池中呢?
那就要用到String的intern()方法,可以做个实验来验证这个方法是否将堆中的字符串对象加到字符串常量池中:
String str2=“java”;
String str3=new String(“java”);
String str4=str3.intern();
System.out.print(str2==str4);
//如果返回true,表示成功,如果false就表示并没有添加进字符串常量池中
我验证所得是true,即intern()方法返回的是一个该字符串在常量池中的引用。
当你
String string="qwer";
String string1=new String("er");
String string2="qw"+string1;
System.out.println(string2==string);
结果为false,说明拼接在堆中的String对象时返回的引用并不指向字符串常量池
以上文章,如有错误,请批评指正 。
分享到:
相关推荐
第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: 揭秘JVM字符串常量池和Java堆-01第4节: ...
在Java编程语言中,字符串常量池(String Constant Pool)是一个重要的概念,它与程序的内存管理和性能优化密切相关。理解这个概念对于任何Java开发者来说都至关重要。字符串常量池是Java虚拟机(JVM)在运行时为...
为了提高效率和内存管理,Java虚拟机(JVM)引入了字符串常量池这一概念。字符串常量池是一个特殊的区域,它存储了程序中所有的字符串常量,避免了多次创建相同的字符串对象。本文将详细探讨字符串常量池的存储方式...
**StringTable(字符串常量池)详解** 在Java编程语言中,`StringTable`是一个重要的概念,它涉及到字符串对象的创建、存储以及内存管理。理解`StringTable`的工作原理对于优化程序性能和节省内存资源至关重要。 #...
String int 字符串常量池 包装类型 函数参数 值传递引用传递 的 内存分配例子——源码 public static void fun_ref (Ref_test ref_out){ Ref_test ref_in=new Ref_test(); ref_in.s1="in"; //ref_out.s1=...
Java中的字符串常量池是Java虚拟机(JVM)为了优化字符串对象的使用而设计的一个特殊内存区域。这个池主要用于存储字符串字面量,也就是在程序中直接出现的字符串值,比如`"hello"`。其核心目的是减少内存的消耗和...
Java中的字符串常量池是Java虚拟机(JVM)为了优化字符串对象的使用而设立的一个特殊区域,它存储了程序中所有的字符串字面量。在Java中,字符串是不可变的,这意味着一旦创建,就不能修改。这个特性使得字符串常量...
Java String 字符串常量池解析 Java 中的字符串常量池是一种为了提高性能和减少内存开销的机制。它是 JVM 实例化字符串常量时进行的一些优化,主要是为了减少字符串对象的创建和存储。 字符串常量池的设计思想是...
本文将深入探讨C#中的CLR(Common Language Runtime)内存字符串常量池,以及它如何处理和优化字符串。 首先,我们需要理解C#中的内存模型。在C#中,内存分为两种主要区域:堆(Heap)和栈(Stack)。栈主要用于...
"深入解析JVM之内存结构及字符串常量池" JVM(Java Virtual Machine)是Java语言的核心组件之一,负责将Java代码编译成机器代码并执行。JVM的内存结构是Java开发者需要了解的基础知识之一,本文将深入解析JVM之内存...
字符串常量池和intern 字符串常量池是Java语言中的一种机制,旨在节省空间和提高性能。它是一个内存区域,所有的Java类共享这个池子。字符串常量池的设计思想是为了解决字符串的频繁创建问题,减少内存开销和提高...
在实际开发中,我们还需要关注JVM的其他重要概念,如类加载机制(加载、验证、准备、解析、初始化)、类文件结构(魔数、版本号、常量池等)、垃圾回收算法(如标记-清除、复制、标记-整理、分代收集)以及执行引擎...
- **字符串字面量的处理**:当程序尝试创建一个新的字符串字面量时,JVM首先会检查字符串常量池中是否存在该字符串。如果存在,则返回已存在的字符串对象;如果不存在,则创建一个新的字符串对象并将其放入字符串...
在JDK 1.6及以前,字符串常量池位于方法区(也称为永久代),而在JDK 1.7中,随着永久代逐渐被移除,字符串常量池被移到堆中。到了JDK 1.8及以后,永久代完全消失,元空间取代了它的位置,但字符串常量池仍然存在于...
在 Java6 中,字符串常量池是放在 Perm 空间的,而从 Java7 开始,字符串常量池被移到 Heap 空间。 Perm 空间是一个固定大小的内存区域,用于存储类的元数据、方法、字段和字符串常量池等信息。当 Perm 空间接近满的...
而在第二行比较中,由于 `"hello"` 和 `"world"` 都是字符串字面量,它们会被合并成一个 `"helloworld"` 字符串字面量,这使得 `s3` 与 `"hello" + "world"` 实际上都指向字符串常量池中的同一个对象。 通过使用反...
- 字符串常量池是JVM内存中的一个特殊区域,用于存放所有的字符串字面量。当创建一个`String`对象时,如果常量池中已经存在相同内容的字符串,那么将返回该字符串的引用,而不是创建新的对象。 4. **字符串比较**...
jvm如何处理长字符串?java的classs文件中,constant_utf8_info的长度是u2,也就是说,一个字符串最长是65535个字节,但是,在本机做测试,超过这个长度的字符串也是允许的,原因是什么?
字符串常量池在JDK8之前位于永久代,但在变化后,它被移出永久代,仍然保留在堆内存中,可能是为了更方便地进行垃圾回收。与此相似,整型常量池也独立出来,用于存储基本类型整数的常量。 整体来看,JDK8的JVM内存...