首页 > 其他分享 >String s=new String(“hello”)的执行过程

String s=new String(“hello”)的执行过程

时间:2023-07-10 15:11:07浏览次数:30  
标签:常量 bytes str 字符串 new hello String

一. 介绍

  String 是Java.long包下的String类,是一个特殊的引用类型,用于表示字符串。它提供了许多方法来操作和处理字符串,比如连接、截取、查找、替换等。String类内部使用字符数组( char[] ) 来存储字符串的内容,value字段被final修饰,String对象一旦创建后,其值就不可改变。String对象的值存储在常量池中,每次修改操作都会创建一个新的字符串对象,并且如果常量池中已经存在相同内容的字符串,就会直接引用该字符串而不创建新对象。

  String 常见的两种赋值方式:

    1. 直接赋值:通过使用双引号将字符串文字包围起来进行赋值,例如:String str = "Hello World!";

    2. 构造函数:通过调用String类的构造函数来创建字符串对象并进行赋值,例如:String str = new String("Hello World!");

 

二. 执行过程

    在了解执行过程前,先明白常量池的作用,String为什么要引用常量池?

      String类引用常量池的目的是提高内存利用率和性能。常量池是Java虚拟机中用于存储字符串常量的一块区域,它位于堆区之外,属于方法区的一部分。     

      当我们使用双引号创建一个字符串对象时,如果常量池中已经存在相同内容的字符串,则不会再创建新的对象,而是直接引用已存在的字符串对象。这样可以节约内存空间,避免不必要的对象创建。     

      另外,String类的一些常用方法如equals()和hashCode()等都依赖于常量池的引用,如果不使用常量池,那么每次字符串比较和哈希计算都需要逐个字符比较,效率较低。而通过引用常量池,可以利用字符串对象的唯一性快速进行比较和哈希计算,提高了程序的执行效率。     

    总而言之,引用常量池可以有效地节省内存开销,并提升字符串操作的性能。

 

  1. 直接赋值的执行过程:

   - 编译阶段,当遇到一个字符串直接赋值的语句,例如:String str = "Hello";  编译器会查询该字符在常量池("Hello")在常量池中是否存在;

          如果常量池中不存在相同的字符串"Hello",则会在常量池创建新的字符串对象;

          如果常量池中存在相同字符串"Hello",则直接返回该字符串的引用;

   - 运行阶段,变量 String str 会在栈内存中占用空间,JVM会将字符串常量的引用指向变量str。这样,变量str就引用了常量池中的字符串对象。

  

  2. 构造函数的执行过程:

   - 编译阶段:如果传入的参数是字符串常量,例如:String str = new String("hello");  编译器会在编译期间将其作为字符串常量处理,并在常量池中创建一个对应的字符串对象。如果已经存在相同内容的字符串常量,则不会重复创建,而是共享已存在的对象。

   - 运行阶段:String  str = new String() 左进栈 ,右进堆;先进栈,后进堆;

         在栈内存上分配空间,创建一个名为str的引用变量,用来存储引用地址;

         在堆内存中创建一个新的String对象,并引用常量池中的字符串地址。

        

三. 区别

   1. 内存分配

    String str = "hello" 的方式 JVM 会将其分配到常量池中,此时仅产生一个字符串对象的内存空间。

    String str = new String("hello”),会在堆内存中new一个对象,若常量池中没有该引用,则会在创建在常量池中创建新的字符串,因此使用new String() 会比直接赋值占用内存多。

  2.  灵活度

    String str = "hello" ,仅支持字符串之间的引用了;

    String str = new String("hello”) ,构造方法提供了更灵活的方式来创建字符串对象,并且可以通过转换类型的功能满足不同的需求。需要注意的是,这些构造方法创建的字符串对象是不可变的,即不能修改其内容。

 

四. 扩展

  String中的构造方法,支持哪种类型转换

    

 构造方法使用方式:

   public static void main(String[] args) throws UnsupportedEncodingException {
        byte[] bytes = {99, 100, 101, 102};
        // public String(byte bytes[])
        // 通过使用平台的默认字符集解码指定的字节数组来构造新的 String 。
        String str1 = new String(bytes);
        System.out.println(str1);

        // public String(byte bytes[], Charset charset)
        // 指定字符集,构建一个新的String字符串
        // bytes[]:字节数组,包含要构建字符串的字符。
        // charset: charset参数指定要使用的字符集
        Charset charset = Charset.forName("UTF-8");
        String str2 = new String(bytes, charset);
        System.out.println(str2);


        // public String(byte bytes[], int offset, int length)
        // 将字节数组中的一部分截取出来变成一个字符串 offset指的是偏移量或者索引
        // bytes:要转换的字节数组。
        // offset:开始转换的位置,即字节数组的起始索引。
        // length:要转换的字节长度,即要转换的字节数。
        String str3 = new String(bytes, 1, 2);
        System.out.println(str3);


        // public String(byte bytes[], String charsetName)
        // 构造一个新的String由指定用指定的字节的数组解码charset 。
        // byte数组(bytes[]):表示要用于构造字符串的字节数组。
        // 字符集名称(String charsetName):表示将字节数组转换为字符串时,字符集的String类型的名字。
        String str4 = new String(bytes, "utf-8"); //解码需要抛异常
        System.out.println(str4);


        // public String(char value[])
        // 使用字符数组构建新的字符串
        char[] chars = {'a', 'b', 'c', 'd', 'e'};
        String str5 = new String(chars);
        System.out.println(str5);

        // public String(char value[], int offset, int count)
        // 构造方法通过将字符数组的一部分转换为字符串来创建新的字符串对象。
        // value:字符数组,包含要构建字符串的字符。
        // offset:整数,指定字符数组中要开始构建字符串的起始位置的偏移量。
        // count:整数,指定从起始位置开始构建字符串的字符数量。
        String str6 = new String(chars, 2, 3);
        System.out.println(str6);

        // public String(int[] codePoints, int offset, int count)
        // 传入int作为参数,构建新的String字符串,这个int是这个字对应的Unicode(16进制数)
        // codePoints:一个包含 Unicode 码点的整数数组。
        // offset:指定从 codePoints 数组的哪个位置开始获取码点。
        // count:指定要使用的码点数量。
        // 该方法会根据提供的码点数组,从指定位置开始取出指定数量的码点,并将它们组合成一个字符串。
        // 需要注意的是,每个码点都代表一个字符,而不是字节。在 Java 中,Unicode 字符以码点的形式表示,其中一些字符可能由多个码元(code unit)组成。
        int[] codePoints = {104, 101, 108, 108, 111};
        String str7 = new String(codePoints, 1, 4); // 在代码示例中使用的码点是整数值,可以直接使用对应字符的 ASCII 码来表示。
        System.out.println(str7);

        // public String(String original)
        // 常使用的方法
        // original:要复制到新String对象中的字符串。
        String str8 = new String("Hello");
        System.out.println(str8);

        // public String(StringBuffer buffer)
        // 将StringBuffer转换为String,并且在需要不可变字符串的场景中更加适用。
        StringBuffer sbf = new StringBuffer("Hello");
        String str9 = new String(sbf);
        System.out.println(str9);

        // public String(StringBuilder builder)
        StringBuilder sb = new StringBuilder("Hello");
        String str10 = new String(sb);
        System.out.println(str10);

    }

输出结果:
    cdef
    de
    cdef
    abcde
    cde
    ello
    Hello
    Hello
    Hello

 

 

 完!

 

  

标签:常量,bytes,str,字符串,new,hello,String
From: https://www.cnblogs.com/victor-sin/p/17539781.html

相关文章

  • String 源码阅读
    String源码阅读1.属性/**Thevalueisusedforcharacterstorage.*/privatefinalcharvalue[];/**Cachethehashcodeforthestring*/privateinthash;//Defaultto0/**useserialVersionUIDfromJDK1.0.2forinteroperability*/privatestaticfi......
  • CF559B - Equivalent Strings
    首先我们考虑第一种做法,我们搜索\(dp_{x,y,l,r}\)判断\(s[x,y]\)和\(t[l,r]\)是否等价,同时记忆化搜索。但是这样是很明显不行的。如果长度是\(2\)的整次幂,我们仅分析最底层长度为\(1\)的区间,我们发现,任何的\([x,x][y,y](x\len/2)\),都会被搜到一遍。这个可以递归处理,......
  • cyber hello world
    CPP文件#include<cyber/cyber.h>intmain(intargc,char*argv[]){apollo::cyber::Init(argv[0]);//初始化日志AINFO<<"helloworld"<<endl;//输出日志return0;}BUILD文件及编译执行//demo_cc目录下新建buld文件,demo_cc目录即为cpp所在目......
  • String、StringBuffer、StringBuilder 的区别?
    一.介绍String、StringBuffer、StringBuilder:  前言: String、StringBuffer、StringBuilder均在java.lang包下;String: 在Java中,String是一个特殊的引用类型,用于表示文本字符串。它提供了许多方法来操作和处理字符串,比如连接、截取、查找、替换等。String类......
  • String内存模型和Java常用方法
    一、String内存模型1、直接赋值创建string对象内存原理:StringTable(串池):字符串常量池,用来存储字符串,只能是在直接赋值中使用才会存在串池当中(JDK7前串池是在方法区里面,StringTable(串池)在JDK7版本开始从方法区中挪到了堆内存,但是运行机制没有发生变化)eg:首先mian方法进栈,创建变......
  • Object.equals 和 String.equals的区别
    一. 源码展示:1.Object.equals:①引用类型地址值比较,直接返回结果:true||falsepublicclassObject{publicbooleanequals(Objectobj){return(this==obj);}} 2.String.equals:①判断地址值是否相等,若相等返回true,若不......
  • HelloWorld
    HelloWorld1.随便新建一个文件夹,存放代码2.新建一个java文件文件后缀名为.javaHello.java[注意点]系统可能没有显示文件后缀名,我们需要手动打开3.编写代码publicclassHe11o{  publicstaticvoidmain(string[]args){    System.out.print("Hello,World!");......
  • AtCoder Grand Contest 058 D Yet Another ABC String
    洛谷传送门AtCoder传送门OrzH6_6Q,感谢他给我们带来了这道容斥好题。这个东西看起来很不好搞。可以尝试容斥。但是我们要容斥啥?钦定ABC不出现,其他任意?感觉还是很难算。观察不合法子串,发现它们很有特点。如果我们钦定\(\texttt{A}\)为\(0\),\(\texttt{B}\)为\(1\),\(\te......
  • CF500C New Year Book Reading 题解
    这一题是一道比较复杂的贪心(对于本蒟蒻来说)假如两本书\(a\)和\(b\),先看\(a\)再看\(b\),那么我们开始的时候就把\(a\)放在上面。这样的话,我们看\(a\)时就不需要搬动\(b\),看\(b\)的时候会搬动\(a\)。而一开始如果把放在上面,看\(a\)的时候需要搬动\(b\),看\(b\)......
  • [oeasy]python0071_字符串类型_str_string_下标运算符_中括号
    回忆上次内容上次分辨了静态类型语言动态类型语言 python属于对类型要求没有那么严格的动态类型语言 对初学者很友好不过很多时候也容易弄不清变量类型 直接修改代码增强程序的可读性把变量的类型明确标......