Java创建字符串的两种方式在地址上的区别

简介: Java创建字符串的两种方式在地址上的区别

一、JAVA中字符串的两种创建方式


我们知道,在Java中有两种创建字符串对象的方式:

1)采用直接赋值的方式赋值


String str1 = "abc";

       采用这种方法去创建字符串时,JVM会在方法区的字符串常量池中寻找这个字符串是否存在,如果存在则不去创建,让创建的对象直接引用其在字符串常量池中的地址;如果不存在则在字符串常量池中创建这个字符串并且返回这个字符串在常量池中的地址。

image.png

编辑

2)采用new关键字新建一个字符串对象


String str2 = new String("abc");
复制代码

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

注意:这种方法本质是在堆区引用字符串常量池中的地址,每次new的对象,在堆上都会创建一个新的对象指向常量池。

image.png

编辑

这两种创建方法其实在创建性能上和访问上是有区别的。(堆区创建带来的性能开销)

二、两种创建方法字符串指向比较


public class Demo1 {
    public static void main(String[] args) {
        String str1 = "abc";
        String str2 = new String("abc");
        String str3 = "abc";
        System.out.println(str1.equals(str2));
        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
    }
}

image.png编辑

这两种方法创建出的字符串虽然内容是一样的,但指向是不一样的。str1和str3直接指向的是常量池的地址,str2指向堆的地址。(参考上面两个图)。

再看下面的代码:

public class Demo1 {
    public static void main(String[] args) {
        String str1 = "abcdef";
        String str2 = "abc";
        String str3 = "def";
        String str4 = "abc" + "def";
        String str5 = str2+str3;
        String str6 = new String("abc"+"def");
        System.out.println(str1 == str4);
        System.out.println(str1 == str5);
        System.out.println(str1 == str6);
    }
}

image.png编辑

这里的str1 == str4很好理解,“abc” + “def”这一步在编译期间会合并成“abcdef”所以输出true;str1 == str5这里的str5出现这样的结果,别的一些说法认为只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。对于所有包含new方式新建对象和直接运用字符串变量的“+”连接表达式,它所产生的新对象都不会被加入字符串池中,都放在了堆内存中。

我对str5的理解是因为str2和str3以及是存在的对象了,所以寻找的第一位置是堆内存所以它并不会再进一步去其对应的常量池中寻找拿出再去拼接这两段字符串。所以只能将他俩在堆区完成操作并且放在堆中导致返回结果是false。

指向地址查看:


public class Demo1 {
    public static void main(String[] args) {
        String str1 = "abcdef";
        String str2 = "abc";
        String str3 = "def";
        String str4 = "abc" + "def";
        String str5 = str2+str3;
        System.out.println(System.identityHashCode(str1));
        System.out.println(System.identityHashCode(str2));
        System.out.println(System.identityHashCode(str3));
        System.out.println(System.identityHashCode(str4));
        System.out.println(System.identityHashCode(str5));
    }
}

image.png

编辑

这样就很明显的看出这些创建方式对象的引用是什么了。

总结:


       new创建出的对象指向均不相等,字符串的创建无论是哪种方式,都需要先在字符串常量池中寻找该字符串是否存在。

如果有不正确的地方请指出,欢迎一起讨论!


相关文章
|
10天前
|
Java
java基础(4)public class 和class的区别及注意事项
本文讲解了Java中`public class`与`class`的区别和注意事项。一个Java源文件中只能有一个`public class`,并且`public class`的类名必须与文件名相同。此外,可以有多个非`public`类。每个类都可以包含一个`main`方法,作为程序的入口点。文章还强调了编译Java文件生成`.class`文件的过程,以及如何使用`java`命令运行编译后的类。
15 3
java基础(4)public class 和class的区别及注意事项
|
5天前
|
Java
java中面向过程和面向对象区别?
java中面向过程和面向对象区别?
15 4
|
5天前
|
Java 数据库
java小工具util系列1:日期和字符串转换工具
java小工具util系列1:日期和字符串转换工具
15 3
|
5天前
|
SQL Java 索引
java小工具util系列2:字符串工具
java小工具util系列2:字符串工具
8 2
ly~
|
8天前
|
安全 Java 大数据
php跟java有什么区别
PHP 和 Java 是两种常用编程语言,各有特色。PHP 语法简洁灵活,适用于快速开发中小型网站,尤其在 Web 脚本和数据库交互中表现出色。Java 则语法严谨,强类型特性使其在企业级应用、移动开发及大数据处理中更受欢迎,具备高稳定性和安全性。通过优化,PHP 性能可提升,而 Java 在大规模应用中表现更佳。总体而言,PHP 开发效率高但维护性稍差,Java 则更注重代码质量和安全性。
ly~
17 5
|
15天前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
|
9天前
|
存储 移动开发 Java
java核心之字符串与编码
java核心之字符串与编码
13 2
|
16天前
|
Java
Java实现:将带时区的时间字符串转换为LocalDateTime对象
通过上述方法,你可以将带时区的时间字符串准确地转换为 `LocalDateTime`对象,这对于处理不需要时区信息的日期和时间场景非常有用。
206 4
|
19天前
|
机器学习/深度学习 人工智能 安全
python和Java的区别以及特性
Python:适合快速开发、易于维护、学习成本低、灵活高效。如果你需要快速上手,写脚本、数据处理、做点机器学习,Python就是你的首选。 Java:适合大型项目、企业级应用,性能要求较高的场景。它类型安全、跨平台能力强,而且有丰富的生态,适合更复杂和规模化的开发。
21 3
|
26天前
|
算法 Oracle Java
Java字符串拼接技术演进及阿里巴巴的贡献
本文主要讲述了Java字符串拼接技术的演进历程,以及阿里巴巴贡献的最新实现 PR 20273。
下一篇
无影云桌面