对于String类型,java官网的文档是这样子描述的:

  String类代表着字符串。java程序中的所有字符串字面值(如"abc")都作为此类的实例实现。

  字符串是常量,他们的值在创建之后不能更改。因为 String 对象是不可变的,所以可以共享。

  那么,jvm是怎么共享这些字符串的呢?

  为了节省内存,提高资源的复用,jvm引入了常量池这个概念,它属于方法区的一部分的,作用之一就是存放编译期间生产的各种字面量和符号引用。而从前面的博文《深入了解JVM—内存区域》我们可以知道,方法区的垃圾回收行为是比较少出现的,该区中的对象基本不会被回收,可以理解成是永久存在的。

  因此,缓存在字符串缓冲区中的字符串对象基本是不被回收的,而jvm也正是通过复用这些对象从而达到共享作用。

  从上一段话中的概念可以知道,一般情况下,只有编译期间可以确定下来的的字符串才能存放到缓冲区中。为什么要强调是一般情况下呢?因为String类为我们提供了一个intern()方法,它可以帮我们将不存在于缓存池中的java字符串添加到缓存池中,并返回缓存池中该字符串对象的引用。

  具体关于intern()方法,后面我们再给出代码做简单说明吧。现在我们将重点放在,什么情况下能够在编译期间直接确定字符串变量值并且将它添加到缓冲区中呢?

  如果程序的字符串连接表达式中没有使用变量或者调用方法,那么该字符串变量的值就能够在编译期间确定下来,并且将该字符换缓存在缓冲区中,同时让该变量指向该字符串;否则将无法利用缓冲区,因为使用了变量和调用了方法之后的字符串变量的值只能在运行期间才能确定连接式的值,也就无法在编译期间确定字符串变量的值,从而无法将字符串变量增加到缓冲区并加以利用。

下面我们来看看如何通过代码及其编译过程来验证上述结论吧。

代码一(没有使用变量或者调用方法):

 1 package com.xiaoxuetu.string;
2
3 public class Test {
4
5 public static void main(String args[]) {
6 String param1 = "abc";
7 String param2 = "abc" + "def";
8 String param3 = "abcdef";
9 }
10 }

更多相关文章

  1. JAVA 静态方法和静态变量和final和※静态import※
  2. Linux(Centos7.X ) 配置Java 环境变量
  3. 与==两个字符串的Java比较是假的? [重复]
  4. 将字符串拆分为字符串数组。
  5. java通过映射取得方法对一个类的变量进行赋值
  6. JavaScript基础——变量、作用域和内存问题
  7. 【读书笔记】JavaScript权威指南 第6版 (三)类型、值和变量
  8. java十进制字符串转十六进制字符串
  9. jQuery(JavaScript)获取文字(字符串)宽度(显示长度)

随机推荐

  1. Android Package的使用情况统计
  2. Android(安卓)屏幕旋转重新调用onCreate
  3. Android 监控程序安装和删除的实现
  4. Android程序开发基础之——页面布局
  5. Android之单元测试
  6. Android(安卓)Memory Management, OutOfM
  7. 在Android(安卓)Studio 2.2上集成OpenCV
  8. github项目解析(五)-->android日志框架
  9. Android(安卓)Retrofit 2.0(一)初次见面请
  10. Android不完全退出主Activity的方法