美文网首页
Java中的String些许理解

Java中的String些许理解

作者: targe | 来源:发表于2019-06-10 17:54 被阅读0次

对于程序员来讲,字符串是最常见的数据类型,我们每天都在和它打交道,今天简单聊下对String的理解。

对于Java来讲,我们编写的代码都会交由JVM执行,所以在讲String之前,先简单介绍下一段Java代码是如何运行的。如图所示,从Class装载到加载到内存中运行过程。


image.png

对于我们来讲,运行时内存空间一般涉及到的就是方法区,堆,栈和常量池。
关于常量池也简单说明下,常量池主要分为:Class文件常量池、运行时常量池,全局字符串常量池。

Class文件常量池是在编译期间生成,由static和final修饰的会存放在Class文件中(典型的就是String,查看String源代码可发现,String由final修饰),这些统称为字面量。另外还包括符号引用,包括类和接口,以及方法的描述。

运行时常量池存放在方法区,它会加载Class文件常量池中的内容,同时该常量池可以动态修改,例如可以使用String的String.intern()方法动态添加到常量池中。

全局字符串常量池,JDK1.7以前该常量池存放在方法区,以后的版本存放在堆中(因为方法区的大小固定,不太适合存放太多内容,而堆可以根据根据物理内存做调整,适合存放大量数据)。

下面来讲下String的几种创建方式

  • String str1= "abc";
  • String str2= new String("abc");
  • String str3= new String("abc").intern();

第一种,首先检查要创建的字符串是否在常量池中存在,如果存在直接引用常量池中的String对象,如果不存在,在常量池中创建新的String对象,然后引用新创建的对象。

说到这里,简单勘误下初学者常见的理解偏差,关于对象和对象引用。对于Java来讲,除了基本数据类型外,形如String str = "abc",str变量即为内存中的对象引用,"abc"为内存中的对象,简单分解上述过程,String str;会在内存(栈内存)中创建一个String类型的对象引用,"abc"代表内存(堆内存)中的对象,对象生成后通过=符号,把该对象的内存地址赋值给str,str在内存中保存的仅仅是对象存放的地址,而不是对象本身,下图描述了内存中的对象和对象引用的存储情况。


image.png

可以看到对象引用是指向堆内存中的对象的,对象对于我们是不可见的,我们操作的都是对象引用。

另简单介绍下堆栈

  • 栈为连续空间,大小和操作系统设置有关,速度快,用来存放临时变量,对象引用,函数调用使用栈,数据结构类似数组,栈为线程私有,外部不能访问
  • 堆为非连续空间,大小可以根据物理内存调整,速度较慢,用来存放对象,空间不连续,数据结构类似链表,堆为线程共享

第二种,会检查其中的字符串本身(abc)是否在常量池中,如果在常量池中即引用常量池中的abc对象在堆内存中生成String对象,str引用的是堆中创建的对象,而不是常量池中的String对象。

第三种,intern()方法会检查字符串是否在常量池中,在的话引用常量池中String对象,不在的话在常量池中创建新的String对象并引用。

对于第一种和第三种intern可以动态的缓存String对象,可以减少存储大量重复的String对象所需的内存空间。但需要注意的是常量池采用hashtable实现,如果对象太多,会增加遍历时间。

关于intern(),引用一张图片说明实际过程

public static void main(String[] args) {
    String s = new String("1");
    s.intern();
    String s2 = "1";
    System.out.println(s == s2);

    String s3 = new String("1") + new String("1");
    s3.intern();
    String s4 = "11";
    System.out.println(s3 == s4);
}
image.png

引用自美团技术团队博客,引用地址 https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html

相关文章

  • Java中的String些许理解

    对于程序员来讲,字符串是最常见的数据类型,我们每天都在和它打交道,今天简单聊下对String的理解。 对于Java...

  • 理解Java中的String

    1. String是如何实现的? 里面是char数组实现的,最新的版本换成了byte数组(ASCII占1位,中文的...

  • 【转】Java中的String:水深几许?

    对Java中String的理解一直源于C++中的String,但越来越不对劲。 从字符串常量到String对象,到...

  • Java String 理解

    我们经常会面对一个问题,String 是最基本的数据类型吗?String 是值类型还是引用类型? 首先我们来回答第...

  • Java的String理解

    String对象方式的创建方式 查看main的字节码 //1.new的方式创建String s = new Str...

  • String、StringBuffer、StringBuilde

    理解Java的字符串,String、StringBuffer、StringBuilder有什么区别? String...

  • 深入理解Java中的String

    String类 先看一下源码(jdk1.8.0_144)中的对于类的定义 首先可以看到String类是被final...

  • 深入理解java中的String

    今天咱们一起来说说java家族中的使用频率最广泛的String String的特性在Sring源码的类注释当中有如...

  • JAVA中String.intern的理解

    intern() 方法返回字符串对象的规范化表示形式。 它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 ...

  • String源码阅读

    String源码阅读 wiki 通过反编译深入理解Java String及intern 成神之路-基础篇 Java...

网友评论

      本文标题:Java中的String些许理解

      本文链接:https://www.haomeiwen.com/subject/sbnzxctx.html