`

JVM对String常量表达式的处理和优化

    博客分类:
  • JVM
 
阅读更多
1.看看下面这段代码执行结果是什么?
String a = "ab";
String b = "a" + "b";
System.out.println((a == b));  //它的执行结果为true;

2.下面这段代码的执行结果是什么?
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println((a == b));   //执行结果为false

以上两个执行结果的原因分析:
    String b = "a" + "b";编译器将这个"a" + "b"作为常量表达式,在编译时进行优化,直接取结果"ab",这样这个问题退化
    String a = "ab";
    String b = "ab";
    System.out.println((a == b));
    然后根据3的解释,得到结果true

javap工具执行查看字节码如下:

0:   ldc     #16; //String ab

2:   astore_1

3:   ldc     #16; //String ab

5:   astore_2

6:   getstatic       #18; //Field java/lang/System.out:Ljava/io/PrintStream;

9:   aload_1

10:  aload_2

11:  if_acmpne       18

14:  iconst_1

15:  goto    19

18:  iconst_0

19:  invokevirtual   #24; //Method java/io/PrintStream.println:(Z)V

22:  return

通过 0:   ldc     #16; //String ab和 3:   ldc     #16; //String ab ,知道该java文件通过编译器编译后都变为    String b = "ab"; 和作者分析的一样。

===========================
对于第二个程序这个好理解,"a" + bb中的bb是变量,不能进行优化。javap查看字节码如下:
0:   ldc     #16; //String ab

   2:   astore_1

   3:   ldc     #18; //String b

   5:   astore_2

   6:   new     #20; //class java/lang/StringBuilder

   9:   dup

   10:  ldc     #22; //String a

   12:  invokespecial   #24; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V

   15:  aload_2

   16:  invokevirtual   #27; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

   19:  invokevirtual   #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

   22:  astore_3

   23:  getstatic       #35; //Field java/lang/System.out:Ljava/io/PrintStream;

   26:  aload_1

   27:  aload_3

   28:  if_acmpne       35

   31:  iconst_1

   32:  goto    36

   35:  iconst_0

   36:  invokevirtual   #41; //Method java/io/PrintStream.println:(Z)V

   39:  return


String+String的操作是在运行时进行的,则会产生新的对象,而不是直接从jvm的string池中获取。


===============================
再看下面两个例子:

String a = "ab";
final String bb = "b";
String b = "a" + bb;
System.out.println((a == b));   //result = true


String a = "ab";
final String bb = getBB();
String b = "a" + bb;
System.out.println((a == b));    //result = false
private static String getBB() {
return "b";
}


查看下面的字节码如下:
  0:   ldc     #16; //String ab

   2:   astore_1

   3:   invokestatic    #18; //Method getBB:()Ljava/lang/String;

   6:   astore_2

   7:   new     #22; //class java/lang/StringBuilder

   10:  dup

   11:  ldc     #24; //String a

   13:  invokespecial   #26; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V

   16:  aload_2

   17:  invokevirtual   #29; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

   20:  invokevirtual   #33; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

   23:  astore_3

   24:  getstatic       #36; //Field java/lang/System.out:Ljava/io/PrintStream;

   27:  aload_1

   28:  aload_3

   29:  if_acmpne       36

   32:  iconst_1

   33:  goto    37

   36:  iconst_0

   37:  invokevirtual   #42; //Method java/io/PrintStream.println:(Z)V

   40:  return


  分析:0:   ldc     #16; //String ab 变量a的值直接指向常量池中的‘ab’,

   通过下面的分析可知 变量2通过StringBuilder进行string操作。











分享到:
评论

相关推荐

    String 优化

    通过理解`String`对象在JVM中的存储方式和优化技巧,开发者可以在编写代码时做出更明智的选择,从而提高程序的性能,特别是在处理大量字符串的场景下,如文本分析和大数据处理。在Android应用开发中,内存管理尤其...

    对String的深入理解

    当使用`+`进行字符串连接时,JVM会自动处理字符串转换和连接过程。对于`str = 1+2+str+3+4;`这样的表达式,每次`+`运算都会生成一个新的`String`对象。在这个例子中,会产生5个对象:原始的"jf",数字1转换的字符串...

    String和StringBuffer专题

    然而,值得注意的是,如果字符串连接是在编译时就能确定的,即字符串连接是在常量表达式中,那么JVM会自动优化这些连接,使用字节码指令`StringBuilder`(在Java 5之后引入的单线程版本`StringBuffer`)进行连接,...

    JVM内幕:java虚拟机详解

    ### JVM内幕:java虚拟机详解 #### 一、概述 ...理解JVM的工作原理对于优化Java程序、解决性能问题具有重要意义。通过深入学习JVM的各个组件及其工作方式,开发人员可以更好地掌握Java编程技巧,提升软件质量。

    Java中的String池

    通过以上分析可以看出,在Java中理解和掌握String池的概念对于优化程序性能至关重要。正确使用字符串字面量、`new`关键字以及`intern()`方法可以帮助开发者更高效地管理和使用字符串资源。同时,需要注意的是,在...

    String.zip

    本篇文章将深入探讨`String`的一般用法和处理,包括其通用方法、字符串到数组的转换以及字符串数据的运算。 ### 1. `String`类的创建与初始化 创建`String`对象有多种方式: - 直接赋值:`String str = "Hello, ...

    java虚拟机规范7和8

    在JVM 7和8中,对类加载的双亲委派模型有所优化,确保了类加载的唯一性和安全性。 2. **内存模型** JVM内存模型定义了程序中变量的可见性和一致性,包括堆内存、栈内存、方法区、程序计数器、本地方法栈等区域。...

    String 字符串讲解

    在Java编程语言中,`String`是一个非常重要的类,它被广泛用于处理文本数据。String对象是不可变的,这意味着一旦创建,就不能更改其内容。接下来我们将深入探讨`String`类的一些关键知识点。 1. **创建字符串对象*...

    深入了解java中的String-字符串(csdn)————程序.pdf

    4. JVM对字符串的优化: - 字符串连接优化:JVM会尝试合并连续的字符串字面量,例如`String str = "hi," + "lao" + "wang";`会被优化为`String str = "hi,laowang";` 5. 常用的String方法: - `concat()`:连接两...

    【Java编程教程】详解Java String字符串.pdf

    字符串在内存中的处理非常特别,它们存储在称为“字符串常量池”的区域,这是一个优化内存使用的策略。当使用字符串字面量(即双引号包围的文本)创建字符串时,Java虚拟机(JVM)会首先查看字符串常量池,如果字符...

    StringManipulation-9.9.0

    "StringManipulation-9.9.0"可能是一个专门用于处理字符串的库或工具包,其版本号9.9.0表示这是一个经过多次迭代和优化的成熟版本。"idea"标签则暗示这可能与IntelliJ IDEA,一个广泛使用的Java开发集成环境有关。 ...

    java细节优化代码1.0版本.zip

    在Java编程领域,优化代码是...这个1.0版本的优化代码可能还包括对这些点的具体实践示例和解释,帮助开发者理解并应用到自己的项目中。通过深入学习和实践这些优化技巧,可以显著提升Java程序的运行效率和用户体验。

    JDK14-java-virtual-machine-guide.pdf

    Java虚拟机(JVM)是Java平台...总的来说,JDK14的Java虚拟机指南详细涵盖了JVM的新功能、优化和使用方法,对于Java开发者来说,深入学习这部分内容能提升开发效率,优化代码性能,更好地利用Java平台提供的各种功能。

    深入理解Java:String

    非堆内存则包含方法区、JVM内部处理所需的内存以及类结构和方法代码。方法区中存储了类的常量池,包括字符串字面量和其他常量。 对于字符串常量,它们的值通常存储在方法区的常量池中。常量池是一个有序集合,包含...

    Java string不可变原理实例解析

    5. **效率**:由于String对象是不可变的,编译器和JVM可以对它们进行优化,比如字符串连接操作(`+`运算符)在某些情况下会被优化为StringBuilder或StringBuffer的append操作,这在处理大量字符串连接时能显著提升...

    Java jdk7.rar

    4. switch 改进:switch语句支持字符串,并允许在case标签后面使用常量表达式。 5. NIO.2:提供了新的文件系统API,包括Path类,便于文件路径操作;WatchService接口,用于监视文件系统更改事件。 6.钻石操作符...

    Java语言程序设计:JAVA_8_常用实用类.ppt

    值得注意的是,`String`类被声明为`final`,这意味着我们不能创建它的子类,它提供了丰富的功能来操作和处理字符串。 ### 8.1 构造字符串对象 1. **常量对象**:在Java中,字符串常量是用双引号括起来的字符序列,...

Global site tag (gtag.js) - Google Analytics