`
m635674608
  • 浏览: 5029072 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

java String 之字节码解析

 
阅读更多

关于java  string 的面试题有很多。。。网上的说法也有很多中。。。。

 在这我解析一下string 的用法的字节码。。。。

public class C{
		public C(){

		}
	public C(String a){
		 this.str=a;
		}
	
 String str0 = "min0";	
 static	String str = "min";
 static	String str2 = "min2";
 final	String str3 = "minmin2";
 final String str4 = "min3";
 public void t(int b){
		System.out.println("min"+str2);
		System.out.println("t--"+str3);
		System.out.println(str4+str3);
		System.out.println(str0+str);
	}
	public static void main(String[] args) {
		new A().t(2);
	
	}

}

   通过javap -verbose 查看一下字节码的存储信息如下

 

Compiled from "C.java"
public class C extends java.lang.Object
  SourceFile: "C.java"
  minor version: 0 //class文件的次版本号
  major version: 49//class文件的主版本号
  Constant pool://常量池
  
//Method:方法 
 //Field:字段 
 //String:字符串 
 //Asciz:这个Asciz表示是CONSTANT_Utf8吧,因为C ONSTANT_Utf8可以是存储四种基本信息类型:文字字符串、被定义的类和接口描述、对其他类或接口的符号引用以及属性相关的字符串。 
 //NameAndType:变量名的类型 
 //Class:类 
  
const #1 = Method       #24.#44;        //  java/lang/Object."<init>":()V //CONSTANT_Methodref_info (10)
const #2 = String       #45;    //  min0     //字符串常量池中的常量 CONSTANT_String_info (8)
const #3 = Field        #23.#46;        //  C.str0:Ljava/lang/String;//没有static修饰的字段记录字段信息
const #4 = String       #47;    //  minmin2  //字符串常量池中的常量 CONSTANT_String_info (8)
const #5 = Field        #23.#48;        //  C.str3:Ljava/lang/String;//没有static修饰的字段
const #6 = String       #49;    //  min3    //字符串常量池中的常量
const #7 = Field        #23.#50;        //  C.str4:Ljava/lang/String;//没有static修饰的字段
const #8 = Field        #23.#51;        //  C.str:Ljava/lang/String;//static修饰的字段
const #9 = Field        #52.#53;        //  java/lang/System.out:Ljava/io/PrintS
tream;
const #10 = class       #54;    //  java/lang/StringBuilder 用于记录类或接口名CONSTANT_Class_info
const #11 = Method      #10.#44;        //  java/lang/StringBuilder."<init>":()V//用于记录方法信息 CONSTANT_Methodref_info

const #12 = String      #55;    //  min    //字符串常量池中的常量CONSTANT_String_info (8)
const #13 = Method      #10.#56;        //  java/lang/StringBuilder.append:(Ljav
a/lang/String;)Ljava/lang/StringBuilder;////用于记录方法信息 CONSTANT_Methodref_info
const #14 = Field       #23.#57;        //  C.str2:Ljava/lang/String;//static修饰的字段
const #15 = Method      #10.#58;        //  java/lang/StringBuilder.toString:()L
java/lang/String;
const #16 = Method      #59.#60;        //  java/io/PrintStream.println:(Ljava/l
ang/String;)V
const #17 = String      #61;    //  t--minmin2   //字符串常量池中的常量
const #18 = String      #62;    //  min3minmin2  //字符串常量池中的常量
const #19 = class       #63;    //  A
const #20 = Method      #19.#44;        //  A."<init>":()V
const #21 = Method      #19.#64;        //  A.t:(I)V
const #22 = String      #65;    //  min2
const #23 = class       #66;    //  C
const #24 = class       #67;    //  java/lang/Object
const #25 = Asciz       str0;
const #26 = Asciz       Ljava/lang/String;;
const #27 = Asciz       str;
const #28 = Asciz       str2;
const #29 = Asciz       str3;
const #30 = Asciz       ConstantValue;
const #31 = Asciz       str4;
const #32 = Asciz       <init>;
const #33 = Asciz       ()V;
const #34 = Asciz       Code;
const #35 = Asciz       LineNumberTable;
const #36 = Asciz       (Ljava/lang/String;)V;
const #37 = Asciz       t;
const #38 = Asciz       (I)V;
const #39 = Asciz       main;
const #40 = Asciz       ([Ljava/lang/String;)V;
const #41 = Asciz       <clinit>;
const #42 = Asciz       SourceFile;
const #43 = Asciz       C.java;
const #44 = NameAndType #32:#33;//  "<init>":()V//记录方法或字段的名称(name)和描述符(descriptor)
const #45 = Asciz       min0;
const #46 = NameAndType #25:#26;//  str0:Ljava/lang/String;// CONSTANT_NameAndType_info
const #47 = Asciz       minmin2;
const #48 = NameAndType #29:#26;//  str3:Ljava/lang/String;
const #49 = Asciz       min3;
const #50 = NameAndType #31:#26;//  str4:Ljava/lang/String;
const #51 = NameAndType #27:#26;//  str:Ljava/lang/String;
const #52 = class       #68;    //  java/lang/System
const #53 = NameAndType #69:#70;//  out:Ljava/io/PrintStream;
const #54 = Asciz       java/lang/StringBuilder;
const #55 = Asciz       min;
const #56 = NameAndType #71:#72;//  append:(Ljava/lang/String;)Ljava/lang/String
Builder;
const #57 = NameAndType #28:#26;//  str2:Ljava/lang/String;
const #58 = NameAndType #73:#74;//  toString:()Ljava/lang/String;
const #59 = class       #75;    //  java/io/PrintStream
const #60 = NameAndType #76:#36;//  println:(Ljava/lang/String;)V
const #61 = Asciz       t--minmin2;
const #62 = Asciz       min3minmin2;
const #63 = Asciz       A;
const #64 = NameAndType #37:#38;//  t:(I)V
const #65 = Asciz       min2;
const #66 = Asciz       C;
const #67 = Asciz       java/lang/Object;
const #68 = Asciz       java/lang/System;
const #69 = Asciz       out;
const #70 = Asciz       Ljava/io/PrintStream;;
const #71 = Asciz       append;
const #72 = Asciz       (Ljava/lang/String;)Ljava/lang/StringBuilder;;
const #73 = Asciz       toString;
const #74 = Asciz       ()Ljava/lang/String;;
const #75 = Asciz       java/io/PrintStream;
const #76 = Asciz       println;

{
java.lang.String str0;

static java.lang.String str;

static java.lang.String str2;

final java.lang.String str3;
  Constant value: String minmin2
final java.lang.String str4;
  Constant value: String min3
  
//如下的Locals表示方法内局部变量个数,该例中是1,有些人疑惑的是Dog()中明明没有参数啊,应该是0啊!      
//当线程调用一个方法的时候,jvm会开辟一个帧出来,这个帧包括操作栈、局部变量列表、常量池的引用      
//非static方法,在调用的时候都会给方法默认加上一个当前对象(this)类型的参数,不需要在方法中定义,      
//这个时候局部变量列表中index为0的位置保存的是this,其他索引号按变量定义顺序累加      
//static方法不依赖对象,所以不用传this      
//Args_size表示参数个数,public C();会传一个this进去,所以value是1    
public C();
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V //调用父类的构造函数
   4:   aload_0
   5:   ldc     #2; //String min0
   7:   putfield        #3; //Field str0:Ljava/lang/String;
   10:  aload_0
   11:  ldc     #4; //String minmin2
   13:  putfield        #5; //Field str3:Ljava/lang/String;
   16:  aload_0
   17:  ldc     #6; //String min3
   19:  putfield        #7; //Field str4:Ljava/lang/String;
   22:  return
  LineNumberTable:
   line 6: 0
   line 14: 4
   line 17: 10
   line 18: 16
   line 8: 22

//invokespecial  //调用构造方法、父类方法      
invokevirtual  //调用普通方法(非构造方法、static方法)      
invokestatic   //调用static方法    
public C(java.lang.String);
  Code:
   Stack=2, Locals=2, Args_size=2
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V //调用父类构造方法
   4:   aload_0
   5:   ldc     #2; //String min0 //将将常量池中的常量压入方法栈
   7:   putfield        #3; //Field str0:Ljava/lang/String;
   10:  aload_0
   11:  ldc     #4; //String minmin2
   13:  putfield        #5; //Field str3:Ljava/lang/String;
   16:  aload_0
   17:  ldc     #6; //String min3
   19:  putfield        #7; //Field str4:Ljava/lang/String;
   22:  aload_0
   23:  pop
   24:  aload_1
   25:  putstatic       #8; //Field str:Ljava/lang/String;
   28:  return
  LineNumberTable:
   line 10: 0
   line 14: 4
   line 17: 10
   line 18: 16
   line 11: 22
   line 12: 28

public void t(int);
  Code:
   Stack=3, Locals=2, Args_size=2
   0:   getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   new     #10; //class java/lang/StringBuilder  //在堆中分配内存,返回对象引用,压入操作数栈   
   6:   dup   //复制引用到stack(栈) 
   7:   invokespecial   #11; //Method java/lang/StringBuilder."<init>":()V //调用构造方法
   10:  ldc     #12; //String min //将将常量池中的常量压入栈   
   12:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang 
/String;)Ljava/lang/StringBuilder; //调用方法
   15:  getstatic       #14; //Field str2:Ljava/lang/String;//访问static字段
   18:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;//调用方法
   21:  invokevirtual   #15; //Method java/lang/StringBuilder.toString:()Ljava/l
ang/String;//调用方法
   24:  invokevirtual   #16; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V//调用方法
   27:  getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;//访问static字段
   30:  ldc     #17; //String t--minmin2 //将常量池中的常量压入栈
   32:  invokevirtual   #16; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V//调用方法
   35:  getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;
   38:  ldc     #18; //String min3minmin2  //将常量池中的常量压入栈
   40:  invokevirtual   #16; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V//调用方法
   43:  getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;//访问static字段
   46:  new     #10; //class java/lang/StringBuilder //在堆中分配内存,返回对象引用,压入操作数栈  
   49:  dup
   50:  invokespecial   #11; //Method java/lang/StringBuilder."<init>":()V//调用方法
   53:  aload_0
   54:  getfield        #3; //Field str0:Ljava/lang/String;//访问str0字段
   57:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;//调用方法
   60:  getstatic       #8; //Field str:Ljava/lang/String;
   63:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder; //调用方法
   66:  invokevirtual   #15; //Method java/lang/StringBuilder.toString:()Ljava/l
ang/String; //调用方法
   69:  invokevirtual   #16; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V //调用方法
   72:  return
  LineNumberTable:
   line 20: 0
   line 21: 27
   line 22: 35
   line 23: 43
   line 24: 72

public static void main(java.lang.String[]);
  Code:
   Stack=2, Locals=1, Args_size=1
   0:   new     #19; //class A
   3:   dup
   4:   invokespecial   #20; //Method A."<init>":()V
   7:   iconst_2
   8:   invokevirtual   #21; //Method A.t:(I)V
   11:  return
  LineNumberTable:
   line 26: 0
   line 28: 11

static {};
  Code:
   Stack=1, Locals=0, Args_size=0
   0:   ldc     #12; //String min
   2:   putstatic       #8; //Field str:Ljava/lang/String;
   5:   ldc     #22; //String min2
   7:   putstatic       #14; //Field str2:Ljava/lang/String;
   10:  return
  LineNumberTable:
   line 15: 0
   line 16: 5

}

  通过字节码信息我们可以发现

system.out.print("min"+str2);Stringbuilder.append(String).append(I)toString;常量池一个对象2个对象

   0:   getstatic       #9; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   new     #10; //class java/lang/StringBuilder//StringBuilder对象
   6:   dup
   7:   invokespecial   #11; //Method java/lang/StringBuilder."<init>":()V
   10:  ldc     #12; //String min
   12:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
   15:  getstatic       #14; //Field str2:Ljava/lang/String;
   18:  invokevirtual   #13; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
   21:  invokevirtual   #15; //Method java/lang/StringBuilder.toString:()Ljava/l
ang/String;//调用stringbuilder.toString()方法。产生对象
   24:  invokevirtual   #16; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V




 System.out.println(str0+str);

字符串拼接。。。。结果同上

 

 

System.out.println("t--"+str3);

由于str3是final修饰的在编译期间就在常量池中了 t--minmin2

const #17 = String      #61;    //  t--minmin2

 

System.out.println(str4+str3);

由于str4.str3都是final编译常量所以同上

const #62 = Asciz       min3minmin2;

 

 

 

 System.out.println(“你好”+“吗”);

由于编译期间(“你好”+“吗”);已经在String常量池中了。同上

const #19 = String      #64;    //  你好吗

 

 

由于时间问题。写的比较毛糙。先写到这了。。下午还要上班。。先小睡会。。。。。下次在写

 

分享到:
评论
1 楼 q631951221 2011-12-12  
第一个,呵呵,慢慢看,还么看懂

相关推荐

    字节码解析示例与说明解析

    以"Demo字节码的解析.xlsx"为例,我们可能看到一个简单的Java方法的字节码分析。例如,一个简单的`add(int a, int b)`方法可能包含以下字节码: ``` 0: iload_0 // 加载局部变量a到操作数栈 1: iload_1 // 加载局部...

    JAVA字节码操作库 BCEL

    **JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...

    Java String与Byte类型转换

    `MyClass.class`是Java字节码文件,它是由`MyClass.java`源代码编译而来。这个过程包括将源代码中的字符串常量转换为字节码,这涉及到了String到Byte的转换。`input.txt`可能是一个文本文件,其内容可能需要在网络...

    借助jclasslib与javassist修改java class字节码

    `jclasslib`则是一款图形化的Java字节码浏览器,主要用于解析和展示Java字节码文件(`.class`文件)的内容。它可以直观地显示字节码指令和常量池中的信息,并且提供了一定程度上的编辑功能,使得用户可以直接在图形...

    探索Java虚拟机的心脏:字节码执行全解析

    ### 探索Java虚拟机的心脏:字节码执行全解析 #### Java语言概览 Java自1995年由Sun Microsystems(现归Oracle所有)发布以来,已成为全球范围内广泛应用的编程语言。作为一种面向对象的语言,Java将现实世界中的...

    java习题 字节码文件

    - **解析:** Java源代码文件通常以`.java`为扩展名,在经过Java编译器(如javac)编译后会生成字节码文件,其扩展名为`.class`。字节码是一种中间代码形式,可以在任何支持Java虚拟机(JVM)的平台上运行而无需重新...

    java实现解析APK

    首先,APK实际上是一个ZIP格式的压缩包,包含了AndroidManifest.xml、资源文件、dex字节码等。传统的解析方法是通过读取ZIP文件并解析XML文件,但这对于经过加密或加壳处理的APK可能无效,因为它们可能对原始数据...

    java解析txt

    * 2:获得文件句柄当做是输入一个字节码流,需要对这个输入流进行读取 * 3:读取到输入流后,需要读取生成字节流 * 4:一行一行的输出。readline()。 * 备注:需要考虑的是异常情况 * @param filePath */...

    java字节码框架ASM操作字节码的方法浅析

    Java字节码框架ASM是一个强大的库,它允许程序员在运行时动态生成和修改Java类和接口的字节码。ASM提供了对JVM字节码的底层访问,这使得开发者能够实现诸如AOP(面向切面编程)或者元编程等高级功能。 首先,我们...

    JAVAocr图像网页附加码解析读取

    "JAVAocr图像网页附加码解析读取"这个主题聚焦于如何利用Java编程语言和OCR(Optical Character Recognition,光学字符识别)技术来解析和读取网页中的附加码。附加码通常用于验证码,目的是防止自动化的机器人程序...

    Java中解析dex文件

    在Java中解析.dex文件是一项技术挑战,因为这涉及到理解Dalvik字节码和相关的文件结构。本篇将深入探讨如何进行这项工作。 首先,我们需要了解.dex文件的基本结构。一个.dex文件主要由以下几个部分组成: 1. **...

    redis字节码存压缩对象

    这些工具可能包括序列化/反序列化方法,用于将Java对象转换为适合Redis存储的字节码格式,以及压缩和解压缩方法。 - 这样的工具类能够帮助开发者更高效地与 Redis 交互,提高代码的可读性和可维护性,同时降低出错...

    java agent使用全解析

    java agent的使用非常广泛,例如字节码插桩、bTrace、Arthas等。 在使用java agent时,需要在命令行输入java可以看到相应的参数,其中有和java agent相关的:-agentlib:[=&lt;选项&gt;] 加载本机代理库 ,例如 -agentlib:...

    Java练习题库(含答案及解析).pdf

    Java程序的执行由Java虚拟机(Java Virtual Machine,简称JVM)负责,它负责将Java的字节码(.class文件)解释执行。垃圾回收器(Garbage Collector)是JVM的一个组件,用于自动回收不再使用的对象所占的空间,而...

    以太帧的解析程序JAVA实现

    4. 解析MAC地址:从缓冲区中读取12字节,然后转换为`Long`或`String`表示形式。每个MAC地址由6个16进制数字组成,中间用冒号分隔。 5. 处理类型/长度字段:读取两个字节,根据值判断是长度还是协议类型。如果是协议...

    Java代码解析指定apk文件

    `classes.dex`包含所有应用的字节码。`DexFile`类可以用于加载和解析这些文件,但需要额外的库如Apache Commons IO。 7. **获取签名信息**:APK文件在发布前会被签名,以验证其来源和完整性。`java.security.cert`...

    深入字节码 -- ASM 关键接口 ClassVisitor1

    【深入字节码 -- ASM 关键接口 ClassVisitor1】这篇技术文章主要探讨了ASM库在处理Java字节码时的核心接口ClassVisitor及其相关方法。ASM是一个强大的Java字节码操控和分析框架,常用于动态代理、字节码增强以及AOP...

    java 解析ASN.1 编码格式cdr话单文件例子

    4. **解析CDR文件**:在Java代码中,实例化ASN.1编解码器,然后读取CDR文件的字节流,使用编解码器将二进制数据转换为Java对象。以下是一个简化的示例: ```java ASN1InputStream asn1In = new ASN1InputStream...

    java字节码框架ASM的深入学习

    在Java开发中,字节码框架ASM提供了一种强大的工具,允许程序员在运行时动态生成或修改类。ASM是一个底层的库,它直接操作Java字节码,这使得开发者能够在运行时改变类的行为或创建新的类。本文将深入探讨ASM框架的...

    Java中高级核心知识全面解析(精华必看)

    JVM(Java Virtual Machine)是Java程序的运行环境,负责解释字节码并执行程序。JDK(Java Development Kit)是开发工具包,包含JVM、编译器和其他开发工具。JRE(Java Runtime Environment)仅包含运行Java应用程序...

Global site tag (gtag.js) - Google Analytics