首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何只在堆上创建字符串对象,而不是在字符串池中?

在Java中,字符串对象可以通过两种方式创建:在堆上创建和在字符串池中创建。在堆上创建字符串对象可以通过使用String类的构造函数或者使用"+"操作符进行字符串拼接来实现。

要在堆上创建字符串对象,可以使用String类的构造函数,例如:

代码语言:java
复制
String str = new String("Hello World");

这样会在堆上创建一个新的字符串对象,并将其赋值给变量str。

另外,使用"+"操作符进行字符串拼接也会在堆上创建新的字符串对象,例如:

代码语言:java
复制
String str = "Hello" + " World";

在这个例子中,"Hello"和"World"都是字符串字面量,它们会在编译时被编译器优化为一个字符串对象,然后通过"+"操作符进行拼接时,会在堆上创建一个新的字符串对象。

需要注意的是,如果字符串字面量已经存在于字符串池中,那么在使用String类的构造函数创建字符串对象时,会在堆上创建一个新的字符串对象,而不是直接引用字符串池中的对象。

总结起来,要在堆上创建字符串对象而不是在字符串池中,可以使用String类的构造函数或者使用"+"操作符进行字符串拼接。这样可以确保每次创建的都是新的字符串对象。

腾讯云相关产品:腾讯云云服务器(CVM)

腾讯云云服务器(CVM)是腾讯云提供的弹性计算服务,可以满足用户在云端部署应用程序、搭建网站、运行企业级应用等需求。用户可以根据自己的需求选择不同配置的云服务器实例,并且可以根据实际情况进行弹性调整。

产品介绍链接地址:https://cloud.tencent.com/product/cvm

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

016:字符串对象在JVM中是如何存放的

本文首发于公众号:javaadu 典型答案 字符串对象在JVM中可能有两个存放的位置:字符串常量池或堆内存。...使用常量字符串初始化的字符串对象,它的值存放在字符串常量池中 使用字符串构造方法创建的字符串对象,它的值存放在堆内存中 String提供了一个API——java.lang.String.intern()...,这个API可以手动将一个字符串对象的值转移到字符串常量池中。...在1.7之前,字符串常量池是在PermGen区域,这个区域的大小是固定的——不能在运行时根据需要扩大,也不能被垃圾收集器回收,因此如果程序中有太多的字符串调用了intern方法的话,就可能造成OOM。...JVM里字符串常量池它的逻辑在注释里写得很清楚:如果常量池中有这个字符串常量,就直接返回,否则将 该字符串对象的值存入常量池,再返回。

2.2K10
  • CA1831:在合适的情况下,为字符串使用 AsSpan 而不是基于范围的索引器

    Span 上的范围索引器是非复制的 Slice 操作,但对于字符串中的范围索引器,将使用方法 Substring 而不是 Slice。 这会生成字符串所请求部分的副本。...此副本在隐式用作 ReadOnlySpan 或 ReadOnlyMemory 值时常常是不必要的。 如果不需要副本,请使用 AsSpan 方法来避免不必要的副本。...若要解决此规则的冲突,请对字符串使用 AsSpan 而不是基于 Range 的索引器,以避免创建不必要的数据副本。...从显示的选项列表中选择“对字符串使用 AsSpan 而不是基于范围的索引器”。 何时禁止显示警告 如果打算创建副本,可禁止显示此规则的冲突。...ReadOnlySpan 或 ReadOnlyMemory 部分 CA1833:使用 AsSpan 或 AsMemory 而不是基于范围的索引器来获取数组的 Span 或 Memory 部分 另请参阅

    1.1K00

    别再问我 new 字符串创建了几个对象了!我来证明给你看!

    :http://openjdk.java.net/jeps/122 答案解密 认为 new 方式创建了 1 个对象的人认为,new String 只是在堆上创建了一个对象,只有在使用 intern() ...认为 new 方式创建了 2 个对象的人认为,new String 会在堆上创建一个对象,并且在字符串常量池中也创建一个字符串。...认为 new 方式有可能创建 1 个或 2 个对象的人认为,new String 会先去常量池中判断有没有此字符串,如果有则只在堆上创建一个字符串并且指向常量池中的字符串,如果常量池中没有此字符串,则会创建...2 个对象,先在常量池中新建此字符串,然后把此引用返回给堆上的对象,如下图所示: ?...,如果常量池中已经存在此字符串只会在堆上创建一个变量,并指向字符串常量池中的值,如果字符串常量池中没有相关的字符,会先创建字符串在返回此字符串的引用给堆空间的变量。

    40420

    别再问我 new 字符串创建了几个对象了!我来证明给你看!

    认为 new 方式创建了 2 个对象的人认为,new String 会在堆上创建一个对象,并且在字符串常量池中也创建一个字符串。...认为 new 方式有可能创建 1 个或 2 个对象的人认为,new String 会先去常量池中判断有没有此字符串,如果有则只在堆上创建一个字符串并且指向常量池中的字符串,如果常量池中没有此字符串,则会创建...2 个对象,先在常量池中新建此字符串,然后把此引用返回给堆上的对象,如下图所示: [new 字符串常量池.png] 老王认为正确的答案:创建 1 个或者 2 个对象。...其实并不是,这里对比的变量 s1 和 s2 堆上地址,因为堆上的地址是不同的,所以结果一定是 false,如下图所示: [字符串引用.png] 从图中可以看出 s1 和 s2 的引用一定是相同的,而 s3...,如果常量池中已经存在此字符串只会在堆上创建一个变量,并指向字符串常量池中的值,如果字符串常量池中没有相关的字符,会先创建字符串在返回此字符串的引用给堆空间的变量。

    67930

    再也不怕面试官问我,new String(abc)创建了几个对象

    因为字符串是一个常用对象,频繁的创建会严重影响性能,而字符常量池就好比一个缓冲区,用来存放我们的字符串对象,做全局共享。...上面应该是我们在普遍得到的答案,但是我们知道在JDK7开始我们的字符串常量池已经在堆中了,没必要每个String对象都存放在字符串常量池中了,也可以只存放该字符串对象的引用。...而触发resolve的时机就是首次使用该字符串常量,也执行到就是ldc字节码指令; 常见面试题: JVM是如何执行String s = "abc"的,会创建几个对象?...执行String s = "abc"语句的具体情况是: 如果字符串常量池中不存在"abc"对象,那么会在字符串常量池创建一个"abc"对象 如果在字符串常量池中已经有"abc"对象,那么直接将s指向字符串常量池中该...首先明确如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。

    61131

    JAVA中字符串常量池和缓冲池理解与作用「建议收藏」

    ) 注意,在这个里面存储的字符串常量只是一个简单的UTF8编码的字节序列,而不是Java的字符串对象,它就和你在一个txt文本中存储的字符串一样,我们用UTF8格式来打开一个.class文件,可以看到hellohellohellohellohello...2 字符串池 字符串池是Java为了重用String对象而设置的一个缓存池,Java1.7之前设置在方法区上,保存的是String对象;Java1.7之后设置在堆上,保存的是String对象的引用,String...对象本身存在于堆上的其他位置。...你可能会好奇这个String被创建的时机,根据R大的这篇文章,在这条语句所在的类被加载时,如果字符串池中已经存在对应的对象了,那么就什么都不做,如果不存在,就会创建一个对应的String对象,并把其引用放入池中...,就会返回池中的对象,只有当池中没有时才会在堆上创建新对象。

    93220

    字符串常量池

    “为什么要先在字符串常量池中创建对象,然后再在堆上创建呢?这样不就多此一举了?”三妹敏锐地发现了问题。...通常情况下,我们会采用双引号的方式来创建字符串对象,而不是通过 new 关键字的方式: String s = "三妹"; 当执行 String s = "三妹" 时,Java 虚拟机会先在字符串常量池中查找有没有...“三妹”这个字符串对象,如果有,则不创建任何对象,直接将字符串常量池中这个“三妹”的对象地址返回,赋给变量 s;如果没有,在字符串常量池中创建“三妹”这个对象,然后将其地址返回,赋给变量 s。...三妹突然插话到,“有了字符串常量池,就可以通过双引号的方式直接创建字符串对象,不用再通过 new 的方式在堆中创建对象了,对吧?” “是滴。...new 的方式始终会创建一个对象,不管字符串的内容是否已经存在,而双引号的方式会重复利用字符串常量池中已经存在的对象。”我说。

    50940

    通过 Chrome Devtools 的 Memory 工具证明 string 的内存分配方式

    JS 的字符串是怎么分配内存的? 可能大家都知道,字符串存在字符串常量池中,被栈或堆上的变量引用。...如果变量的值是字符串字面量,则在栈上的变量直接引用字符串常量池中的字符串;如果是字符串是 new String 创建的,则会在堆上创建 String 对象,指向字符串常量池中的字符串,栈上变量指向堆中的...的字符串 "guang" 而 Array 中的元素则是指向了不同的 String 对象的地址: 这再一次验证了字符串常量池的存在,以及 String 对象是在堆上分配内存,然后指向字符串常量池的字符串...证明完毕,确实如前面的结论所说:字符串存储在字符串常量池中,字符串字面量直接指向常量池的字符串地址,String 对象会先在堆上分配空间,然后指向字符串常量池的字符串地址。...我们从始至终只创建了一次 "guang" 这个字符串,字符串常量池的好处显而易见了。

    54200

    String字符串—详细总结

    String 概念 不可变的,每一次修改实际上生成新的字符串,并且该字符串的值是修改后的值。new String都是在堆上创建字符串对象 String 被声明为 final,因此它不可被继承。...而只是在常量池中生成一个对原字符串的引用。...,则继续指向同一个字符串值 所以String str2 = new String(“abc”); 此时就创建一个对象,而abc 则是从字符串常量缓冲区中取出来的。...(如:String str3=baseStr + “01”;)会调用stringBuilder.append()在堆上创建新的对象。...JDK 1.7后,intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别,区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用

    46120

    面试题系列第2篇:new String()创建几个对象?有你不知道的

    String str1 = "abc"; // 在常量池中 String str2 = new String("abc"); // 在堆上 当直接赋值时,字符串“abc”会被存储在常量池中,只有1份...当然,如果检索常量池时发现已经存在了对应的字符串,那么只会在堆内创建一个新的String对象,此过程只创建了1个对象。...上面的示意图我们可以看到在堆内创建的String对象的char value[]属性指向了常量池中的char value[]。...,而并没有指向常量池中的字符串。...是不是很有意思?当你掌握了这些底层基本知识,即便面试题的形式如何变化,你必定能一眼识破真相。 下篇文章,(读者提议)我们来讲讲Integer的比较的底层逻辑,欢迎持续关注。

    8.6K83

    面试题:String、StringBuffer 汇总篇

    由于有符号引用的存在,所以 String c = b + 2;不会在编译期间被优化,不会把b+2当做字面常量来处理的,因此这种方式生成的对象事实上是保存在堆上的。因此a和c指向的并不是同一个对象。...在String类中,intern方法是一个本地方法,在JAVA SE6之前,intern方法会在运行时常量池中查找是否存在内容相同的字符串,如果存在则返回指向该字符串的引用,如果不存在,则会将该字符串入池...这段代码在运行期间会创建2个对象么?毫无疑问不可能,用javap -c反编译即可得到JVM执行的字节码内容: ? 很显然,new只调用了一次,也就是说只创建了一个对象。...而这道题目让人混淆的地方就是这里,这段代码在运行期间确实只创建了一个对象,即在堆上创建了"abc"对象。而为什么大家都在说是2个对象呢,这里面要澄清一个概念 该段代码执行过程和类的加载过程是有区别的。...在类加载的过程中,确实在运行时常量池中创建了一个"abc"对象,而在代码执行过程中确实只创建了一个String对象。

    47710

    JDK1.8关于运行时常量池, 字符串常量池的要点

    “abcdef”字符串常量 而不把 “abc” “def”放进常量池) 对于先声明的字符串字面量常量,会放入字符串常量池,但是若使用字面量的引用进行运算就不会把运算后的结果放入字符串常量池中了 (...,只放结果;已经声明的,只放声明 常量池中同时存在字符串常量和字符串引用。...直接赋值和用字符串调用String构造函数都可能导致常量池中生成字符串常量;而intern()方法会尝试将堆中对象的引用放入常量池 String str1 = “a”; String str2...str1和str2对象) String str5 = new String(“ab”);(字符串常量池中不存在”ab”时)在字符换常量池中创建”ab”对象,在堆中生成了一个对象str5, str5...指向堆上new的对象,而str5内部的char value[]则指向常量池中的char value[] 关于这个问题可以参考这篇博客:new String()究竟创建几个对象?

    85720

    JVM运行时数据区域

    (str1==str2);//false 这两种不同的创建方法是有差别的: 第一种方式是在常量池中获取对象("abcd" 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象), 第二种方式一共会创建两个字符串对象..."abcd" 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象,指向这个 "abcd" 字符串字面量; 使用 new 的方式会在堆中创建一个字符串对象。 ?...str2 = "ing"; String str3 = "str" + "ing";//常量池中的对象 String str4 = str1 + str2; //TODO:在堆上创建的新的对象..."abc" 属于字符串字面量,因此编译时期会在常量池中创建一个字符串对象,指向这个 "abcd" 字符串字面量; 使用 new 的方式会在堆中创建一个字符串对象。...(字符串常量"abc"在编译期就已经确定放入常量池,而 Java 堆上的"abc"是在运行期初始化阶段才确定)。

    40240

    java字符串中关于==的理解

    如果"joshua317"在字符串常量池中已经存在,则不会再创建String类型的值为"joshua317"的对象,而是将str指向这个"joshua317"对象内存地址,后续无论用这种方式创建多少个指向...而==判断的是对象内存的地址,所以demo1返回true。下图是用这种方式创建字符串的示例图。...demo2的两个字符串都是通过new的方式创建对象的,所以在堆上有两个String对象,且这两个对象指向字符串常量池中的同一个对象"joshua317",如上图所示,此时str2和str3存储的对象地址就不相同...的引用返回给new出来的对象;如果字符串常量池中有"joshua317",则该句只创建了一个对象,因为该句首先会查找字符串常量池中是否存在"joshua317",如果存在则直接返回"joshua317"...总结 如果是基本数据类型,==判断的是值 如果是对象类型,==判断的是对象的地址 通过直接赋值而不是new的方式给String赋值,如果字符串常量池中有该对象,则不会再创建,此时通过 == 判断,返回的是

    11000

    String类型在JVM中的内存分配

    用引号创建一个字符串的时候,首先会去常量池中寻找有没有相等的这个常量对象,没有的话就在常量池中创建这个常量对象;有的话就直接返回这个常量对象的引用。...书上说,产生差异的原因是:在JDK1.6中,intern()方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中这个字符串实例的引用,而由StringBuilder创建的字符串实例在Java堆上...而JDK1.7的intern()不会再复制实例,只是在常量池中记录首次出现的实例的引用,因此intern()返回的引用和StringBuilder创建的那个字符串的实例是同一个。...,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。...而str1所指向的也是这个堆对象的引用,所以第一个是true。 而第二个,首先查资料发现,由于JVM的 特殊性在JVM启动的时候调用了一些方法,在常量池中已经生成了“java”字符串常量。

    2.9K41

    Java字符串比较面试题详解

    字符串比较 通过字面量赋值创建字符串(如:String s=”hi”),会先在常量池中查找是否存在相同的字符串,若存在,则直接指向该字符串;若不存在,则在常量池中生成一个字符串,再将引用指向该字符串。...通过new String创建字符串,在堆上创建一个,同时在常量池创建一个值相同的对象,但是这两个对象互不相干,如果常量池里已经有了同样的值的对象,只会在堆里新建对象 常量字符串和变量拼接时或者变量与变量拼接时会调用...stringBuilder.append()在堆上创建新的对象,而不会同时在常量池里新建对象 String s = new String("a") + new String("b"); 约等于 StringBuilder...sb = new StringBuilder(); sb.append("a").append("b"); // toString()只会在堆上创建对象("ab"),new String("ab")...会在堆上和常量池都创建 String s = sb.toString(); 调用字符串对象的 intern() 方法时,intern方法会先去常量池找,如果存在,指向常量池中的,如果不存在,在常量池中生成一个对原字符串的引用

    11810

    Java 内存区域详解

    ";//常量池中的对象 String str4 = str1 + str2; //在堆上创建的新的对象 String str5 = "string";//常量池中的对象 System.out.println...String str4 = new StringBuilder().append(str1).append(str2).toString(); 因此,str4 并不是字符串常量池中存在的对象,属于堆上的新对象...使用 new 的方式创建对象的方式如下,可以简单概括为 3 步: 在堆中创建一个字符串对象 检查字符串常量池中是否有和 new 的字符串值相等的字符串常量 如果没有的话需要在字符串常量池中也创建一个值相等的字符串常量...不包含 1.7)的处理方式是在常量池中创建与此 String 内容相同的字符串,并返回常量池中创建的字符串的引用,JDK1.7 以及之后,字符串常量池被从方法区拿到了堆中,jvm 不会在常量池中创建该对象...如果字符串常量池中没有字符串常量“abc”,那么它将首先在字符串常量池中创建,然后在堆空间中创建,因此将创建总共 2 个字符串对象。

    49020

    JVM之StringTable

    如果不是用双引号声明的String对象,可以使用String提供的intern方法:intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。...* 一个对象是:new关键字在堆空间创建的 * 另一个对象是:字符串常量池中的对象"ab"。...String 对象 ldc #3 :在字符串常量池中放入 “ab”(如果之前字符串常量池中没有 “ab” 的话) “ab”作为入参传入,本身就是String类型,此时需要先在常量池中创建对象“ab”...() 方法,会生成一个 String 对象 5.3、有点难的面试题 代码示例 /** * 如何保证变量s指向的是字符串常量池中的数据呢?...“11”   2)s3.intern();jdk6字符串常量池在方法区,jdk7/8字符串常量池在堆中,new String()对象也在堆中,所幸为了节省空间,字符串常量中就不再创建对象了,只保留堆中对象的引用

    6700
    领券