• Java中String对象的存储位置(学习笔记)


    首先,String是final修饰的、immutable对象,它以一个个字符的方式存储在字符数组中。
    其次,String类型创建对象有两种方式:①通过字面量赋值:会先去常量池中查找是否存在相同的字符串,若存在,栈中引用直接指定该字符串;若不存在,在常量池中进行缓存,再将栈中引用指向它。②通过new关键字:每次new出来的都是一个新的对象,在堆中开辟空间进行存储。
    又因为,在JDK1.7的HotSpot中,已经把原本放在永久代的字符串常量池移出,JDK8元空间彻底取代永久代,此时字符串常量池还在堆,所以String变量是以字符数组的形式储在堆。
    证明,str1和str2,指向的是同一个字符数组:

    String str1="ab";
    String str2=new String("ab");
    Field field=str2.getClass().getDeclaredField("value");
    field.setAccessible(true);
    char[] sum=(char[]) field.get(str2);
    sum[0]='w';
    System.out.println(str1);//wb
    System.out.println(str2);//wb

    test直接演示String对象的创建位置:

    package test.string.equal;
    
    public class Main {
        
        /** 
         * 创建了三个对象,"helloworld对象创建在常量池中",每次new String()都会创建一个对象在堆内存中。
         */
        void test() {
         String s1="helloworld"; String s2
    = new String("helloworld"); String s3= new String("helloworld"); } /** * 程序只创建一个字符串对象“Java”,存放在常量池中,所以s1==s2 为true */ void test1(){ String s1="Java"; String s2="Java"; System.out.println(s1==s2); } /** 第一个new String("Java"):创建了两个对象,Java创建于常量池中,String对象创建于堆内存中。 * 第二个new String("Java"):由于常量池中有Java对象,所以只需创建一个对象,String对象创建于堆内存中。 * s1与s2分别指向String对象堆内存,所以s1==s2 为false */ void test2() { String s1=new String("Java"); String s2= new String("Java"); System.out.println(s1==s2); } /** 常量的值在编译的时候就确定了,"hello"、"world"都是常量,因此s2的值在编译的时候也确定了, * s2指向常量池中的"hello world",所以s1==s2为true * */ void test3() { String s1="hello world"; String s2="hello "+"world"; System.out.println(s1==s2); } /** s4由两个String变量相加得到,不能再编译时就确定下来,不能直接引用常量池中的"helloworld"对象,而是在堆内存中创建一个新的String对象并由s4指向 * 所以s1==s4为false * */ void test4() { String s1="helloworld"; String s2="hello"; String s3="world"; String s4=s2+s3; System.out.println(s1==s4); } /** s2与s3被final修饰为宏变量,不可更改,编译器在程序使用该变量的地方直接使用该变量的值进行替代,所以s4的值在编译的时候就为"helloworld" * 指向常量池中的"helloworld"对象 * 所以s1==s4为true * */ void test5() { String s1="helloworld"; final String s2="hello"; final String s3="world"; String s4=s2+s3; System.out.println(s1==s4); } public static void main(String[] args) { Main o = new Main(); o.test1(); o.test2(); o.test3(); o.test4(); o.test5(); } }
  • 相关阅读:
    教你如何用Meterpreter渗透Win系统
    Maven 自动打包上传到私服 Nexus
    从同事的一个提问想到的学习途径
    SAS学习笔记之《SAS编程与数据挖掘商业案例》(1)系统简介和编程基础
    StackOverflowError&OutOfMemoryError区别
    优先使用TimeUnit类中的sleep()
    Java 开源博客 Solo 1.3.0 发布
    Java 开源博客 Solo 1.3.0 发布
    Cleanup failed to process the following paths错误的解决
    Java&Xml教程(六)使用JDOM解析XML文件
  • 原文地址:https://www.cnblogs.com/1693977889zz/p/11393967.html
Copyright © 2020-2023  润新知