编写Test.java。编译完后生成Test.class文件,然后对该文件运行javap -c Test命令,生成字节码指令。阅读并得出结论
一、s1和s2指向常量池的不同常量
①java代码
public class Test {

    public static void main(String[] args) throws IOException {

        String s1="t";

        String s2="m";

    }

}

②反编译能够看到字节码指令运行例如以下:
Compiled from "Test.java"

public class typ.Test extends java.lang.Object{

public typ.Test();

  Code:

   :   aload_0

   ; //Method java/lang/Object."<init>":()V

   :   return



public static void main(java.lang.String[])   throws java.io.IOException;

  Code:

   :   ldc     #19; //String t 进入操作数栈顶

   :   astore_1     //String t 出操作数栈,赋值给变量1。即s1

   ; //String m 进入操作数栈顶

   :   astore_2     //String m 出操作数栈,赋值给变量2,即s2

   :   return

}
从上面能够看出,两次ldc入栈操作分别指向的是常量#19和#21

二、s1和s2指向常量池的同样常量
①java代码
public class Test {

    public static void main(String[] args) throws IOException {

        String s1="t";

        String s2="t";

    }

}
②反编译能够看到字节码指令运行例如以下:
Compiled from "Test.java"

public class typ.Test extends java.lang.Object{

public typ.Test();

  Code:

   :   aload_0

   ; //Method java/lang/Object."<init>":()V

   :   return



public static void main(java.lang.String[])   throws java.io.IOException;

  Code:

   ; //String t 进入操作数栈顶

   :   astore_1     //String t 出操作数栈,赋值给变量1,即s1

   ; //String t 进入操作数栈顶

   :   astore_2     //String t 出操作数栈。赋值给变量2。即s2

   :   return

}
从上面能够看出。两次ldc入栈的操作数都是将指向的常量#19,所以能够看出是s1和s2都是指向常量池的同一个常量“t”

三、进一步看以下
①java代码
public class Test {

    public static void main(String[] args) throws IOException {

        String s1="tm";

        String s2="t"+"m";

    }

}
②反编译能够看到字节码指令运行例如以下:
Compiled from "Test.java"

public class typ.Test extends java.lang.Object{

public typ.Test();

  Code:

   :   aload_0

   ; //Method java/lang/Object."<init>":()V

   :   return



public static void main(java.lang.String[])   throws java.io.IOException;

  Code:

   ; //String tm 进入操作数栈顶

   :   astore_1     //String tm 出操作数栈,赋值给变量1,即s1

   ; //String tm 进入操作数栈顶

   :   astore_2     //String tm 出操作数栈,赋值给变量2。即s2

   :   return

}
能够看出。两次ldc(load命令, 将操作数入栈)入栈的操作数都是将指向的常量#19即“tm”,说明在编译期间,“t”+"m"就已经变为“tm”这一个常量了

四、再进一步
①java代码
public class Test {
    public static void main(String[] args) throws IOException {
        String tmp = "t";
        String s1 = "m";
        String s2 = tmp + "m";
    }

}

②反编译能够看到字节码指令运行例如以下:
Compiled from "Test.java"

public class typ.Test extends java.lang.Object{

public typ.Test();

  Code:

   :   aload_0

   ; //Method java/lang/Object."<init>":()V

   :   return



public static void main(java.lang.String[])   throws java.io.IOException;

  Code:

   ; //String t 进入操作数栈顶

   :   astore_1     //String t 出操作数栈,赋值给变量1,即tmp

   ; //String m 进入操作数栈顶

   :   astore_2     //String m 出操作数栈。赋值给变量2。即s1

   ; //class java/lang/StringBuilder 创建StringBuilder类型对
象 
   :   dup          //复制栈顶一个字长的数据,将复制后的数据压栈 
   :  aload_1      //tmp 进入操作数栈顶

   ; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;

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

   ; //String m

   ; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

   ; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

   :  astore_3

   :  return

}

从上面的代码能够看出。string的相加要通过stringbuilder。而且因为tmp是变量。所以调用的invokevirtual指令(在编译器无法确定),这说明不是
在编译期完毕,因此s1与s2时不相等的

用javap命令反编译来分析字符串问题的更多相关文章

  1. javap命令反编译

    javap命令反编译生成的是程序员可以认识的字节码文件 -help --help -? 输出此用法消息 -version 版本信息,其实是当前javap所在jdk的版本信息,不是class在哪个jdk ...

  2. JDK自带javap命令反编译class文件和Jad反编译class文件(推荐使用jad)

    一.前言 我们在日常学习中,对一个java代码有问题,不知道jvm内部怎么进行解析的时候:有个伟大壮举就是反编译,这样就可以看到jvm内部怎么进行对这个java文件解析的!我们可以使用JDK自带的ja ...

  3. javap 命令 反编译代码

    javap 命令 javap -c classname 一个好的分析class二进制文件的 链接 http://blog.csdn.net/pwlazy/article/details/7954169

  4. 使用javap进行反编译Java枚举

    这是一个枚举类Day.java public enum Day { MONDAY("星期一"), TUESDAY("星期二"), WEDNESDAY(" ...

  5. Java反编译代码分析(一)

    浅析如何读懂这种反编译过来的文件,不喜勿喷. 赋值 Node node; Node node1 = _$3.getChildNodes().item(0); node1; node1; JVM INS ...

  6. 反编译字节码角度分析synchronized关键字的原理

    1.synchronized介绍 synchronized是java关键字.JVM规范中,synchronized关键字用于在线程并发执行时,保证同一时刻,只有一个线程可以执行某个代码块或方法:同时还 ...

  7. java7(1)——反编译深入理解增强的switch(读字节命令实战)

    [本文介绍] 本文主要讲java_7 的改进switch的底层实现.反编译一个使用带String的switch的demo并一步步解析反编译出来的字节命令,从编译的角度解读switch的底层实现. [正 ...

  8. 使用javap反编译class文件

    一个普通的Java类: package org.ccnt.concurrence; public class VolatileTest { public static volatile int rac ...

  9. @使用javap反编译Java字节码文件

    在Sun公司提供的JDK中,就已经内置了Java字节码文件反编译工具javap.exe(位于JDK安装目录的bin文件夹下). 我们可以在dos窗口中使用javap来反汇编指定的Java字节码文件.在 ...

随机推荐

  1. fork进程函数总结

    学习链接: http://blog.csdn.net/jason314/article/details/5640969 http://coolshell.cn/articles/7965.html 搜 ...

  2. Excel VLOOKUP等使用记录

    1.LEFT 函数:LEFT(G2,ROW(INDIRECT("76:"&LEN(G2)))) 截取G2单元格从开头,SIZE=76的部分字符串 2.RIGHT 函数:RI ...

  3. 电脑硬件扫盲--CPU 显卡

    CPU: 主要2个厂商 Inter:core(酷睿) > pentinum(奔腾) > celeron(赛扬) AMD:athlon(速龙) > semporn(闪龙) 主频(GHz ...

  4. Xcode 那些简单实用的插件推荐

    古人云“工欲善其事必先利其器”,打造一个强大的开发环境,是立即提升自身战斗力的绝佳途径!   晾一下我的武器库,欢迎大家选用:)     全能搜索家CodePilot 2.0 ------------ ...

  5. JAVA并发,同步锁性能测试

    测试主要从运行时间差来体现,数据量越大,时间差越明显,例子如下: package com.xt.thinks21_2; /** * 同步锁性能测试 * * @author Administrator ...

  6. HDU 3507 Print Article(CDQ分治+分治DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3507 [题目大意] 将长度为n的数列分段,最小化每段和的平方和. [题解] 根据题目很容易得到dp ...

  7. 给即将面临Noip的二班同学

    给即将面临Noip的二班同学: 我们共同走过了一年,在这里,真正认识彼此…… 失落过,但更多是欢笑…… 或许我们班的信息学竞赛承受着巨大的压力,但正因为这样,我们才学会了坚持:或许我们得不到他人的认可 ...

  8. 《windows程序设计》学习_3.3:利用xp扫雷资源

    #include<windows.h> #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPAR ...

  9. Highlighting an element as it is hovered over (like inspect element in FireBug) - jQuery Forum

    Highlighting an element as it is hovered over (like inspect element in FireBug) - jQuery Forum Highl ...

  10. XML DOM 节点

    来自:w3cschool菜鸟教程 在 DOM 中,XML 文档中的每个成分都是一个节点. DOM 节点 根据 DOM,XML 文档中的每个成分都是一个节点. DOM 是这样规定的: 整个文档是一个文档 ...