首页 > 其他分享 >字符串常量池

字符串常量池

时间:2023-09-29 13:55:18浏览次数:26  
标签:常量 对象 创建 str1 字符串 new String

1.简介

  字符串常量池(String Pool)又称为字符串池。String类是在工作中使用频率非常高的一种对象类型,JVM为了提升性能和减小内存开销,避免字符串的重复创建,维护了一块特殊的内存空间,即字符串常量池。(由String类私有地维护)

  字符串池的一个实现前提:String对象是不可变的。

2.创建字符串

  1.最简单的方式:

public class test {
  public static void main(String[] args) {
    String str1 = "a"; //创建字符串
    String str2 = "a";
    System.out.println(str1==str2);
  }
}

  运行结果为 true

  采用这种方式创建一个字符串时,JVM首先会去字符串池中查找是否存在 "a" 这个对象,如果不存在,则在字符串池中创建 "a" 这个对象,然后将池中 "a" 这个对象的引用地址返回给字符串常量str,这样str会指向池中"aaa"这个字符串对象;如果存在,则不创建任何对象,直接将池中 "a" 这个对象的地址返回,赋给字符串常量。
  上述例子中,在创建str2时,字符串常量池中已经有了 "a" 这个对象,则直接把 "a" 的引用地址返回给str2,这样,str2就指向了 "a" 这个对象,即str1和str2指向了同一个对象,所以str1 == str2为true。

  2.使用new关键字:

public class test {
    public static void main(String[] args) {
        String str1 = new String("a"); //创建字符串
        String str2 = new String("a");
        System.out.println(str1 == str2);
    } 
}

  运行结果为 false

  采用new关键字创建一个字符串对象时,JVM首先在字符串常量池中查找是否存在 "a" 这个字符串对象,如果存在,则不在池中再去创建 "a" 这个对象了,直接在堆中创建一个"a"字符串对象,然后将堆中的这个"a"对象的地址返回赋给引用str1,这样,str1就指向了堆中创建的这个"a"字符串对象;如果不存在,则首先在字符串常量池池中创建一个"a"字符串对象,然后再在堆中创建一个"a"字符串对象,然后将堆中这个"a"字符串对象的地址返回赋给str1引用,这样,str1指向了堆中创建的这个"a"字符串对象。

  上述例子中,采用new关键字创建对象时,每次new出来的都是一个新的对象,即引用str1和str2指向的是两个不同的对象,因此语句
str1 == str2为 false。

字符串池的优缺点

  字符串池的优点是避免了相同内容的字符串的创建,节省了内存,省去了创建相同字符串的时间,同时提升了性能;

  另一方面,字符串池的缺点是牺牲了JVM在常量池中遍历对象所需要的时间,不过其时间成本相比而言比较低

String s = new String("ywzh")创建了几个对象的相关问题

  new String("ywzh")相当于new String(String s1="ywzh"),即先要执行String s1="ywzh",然后再在堆区new一个String对象

  即:

  String s=new String("ywzh")创建了1或2个对象

  String s="ywzh"创建了0或1个对象。

字符串拼接 + 操作符与字符串常量池

  String s1 = "yw";
  String s2 = "zh";
  String s3 = s1 + s2;

执行上述代码时:

  第一步:new一个StringBuilder;

  第二步:append s1;

  第三步:append s2;

  第四步:调用StringBuilder的toString方法;

  即:+操作符的原理是StringBuilder的append方法。

下面是一道面试题:

String s1 = "a";
String s2 = "b";
String s3 = s1+s2;
String s4 = "ab";
System.out.println(s3==s4);

   问题在于拼接之后的"ab"是否会放入常量池。

   StringBuilder的toString方法

   可以看到,返回了一个String对象,并且new好的String对象不会放进常量池里。

  因此 s3 == s4 为false。

 

标签:常量,对象,创建,str1,字符串,new,String
From: https://www.cnblogs.com/ywzh/p/17736886.html

相关文章

  • String字符串经典问题
    publicclassExample{Stringstr=newString("good");char[]ch={'a','b','c'};publicstaticvoidmain(Stringargs[]){Exampleex=newExample();ex.change(ex.str,ex.ch);......
  • JS判断字符串是否全为空
    1、使用trim()方法trim()方法会去除首尾空格,并返回一个处理后的新值<template><divclass="box">content</div></template><scriptsetup>import{ref,reactive,toRefs,watch,computed,defineProps,}from'vue';import{useStore}......
  • 数据结构---字符串
    数据结构---字符串串的定义串是由零个或多个字符顺序排列组成的有限序列空串长度为零的串空白串由一个或多个空格组成的串字符串匹配问题朴素模式匹配模式匹配的查找过程(Find):给定两个字符串变量S和P,其中目标S有n个字符,模式P有m个字符,m<=n。从S的给定位置(通常为S的第......
  • 字符串排序算法+快速排序
    #include<stdio.h>#include<stdlib.h>#include<memory>#include<vector>#include<string>usingnamespacestd;voidswap(int*a,int*b){inttemp=*a;*a=*b;*b=temp;}voidquicksort(int*arr,intsta......
  • python中实现按照固定位数拆分字符串
     001、[root@pc1test2]#lstest.py[root@pc1test2]#cattest.py##测试程序#!/usr/bin/envpython3#-*-coding:utf-8-*-importrestr1="abcdefghijklmn"print(str1)list1=re.findall(".{3}",str1)##按照每3位生成列表print(&qu......
  • Python 中的字符串基础与应用
    在Python中,字符串可以用单引号或双引号括起来。'hello'与"hello"是相同的。您可以使用print()函数显示字符串文字:示例:print("Hello")print('Hello')将字符串分配给变量是通过变量名后跟等号和字符串完成的:示例a="Hello"print(a)多行字符串您可以使用三个引号将多......
  • 2023 ICPC 网络赛2 L Super-palindrome 字符串 border KMP dp
    传送门给出一个\(5000\)长的字符串判断有多少个连续子串是超级回文的。这里超级回文的定义是将字符串分成\(2k\)段每段按照回文对应相等。设\(f_{l,r}\)表示区间\(l,r\)是否是符合要求的。引入\(border\)的定义:最长的前缀和后缀匹配长度。容易想到我们如果暴力枚举每个区间来......
  • 随想录Day8|344. 反转字符串、541. 反转字符串Ⅱ、LCR 122. 路径加密、151. 反转字符
    随想录Day8|344.反转字符串、541.反转字符串Ⅱ、LCR122.路径加密、151.反转字符串里的单词、LCR182.动态口令 题目越来越长了…… 344.反转字符串文章&视频讲解编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数......
  • ASP.NET截取字符串函数
    #region截取指定字数字符串///<summary>///格式化字符串,取字符串前strLength位,其他的用...代替.///计算字符串长度。汉字两个字节,字母一个字节///</summary>///<paramname="str">字符串</param>///<paramname=......
  • string字符串操作
    string字符串操作 usingSystem;usingSystem.Linq;usingUnityEngine;publicclassGuse:MonoBehaviour{voidStart(){stringstr="ASc_b16U2ja";string[]vari=str.Split('_');//根据单个字符切割Debug.Log(v......