- 浏览: 5029072 次
- 性别:
- 来自: 南京
文章分类
- 全部博客 (2844)
- java (1094)
- hadoop (37)
- jvm (39)
- hbase (11)
- sql (25)
- 异常 (83)
- div css (6)
- 数据库 (95)
- 有趣的code (15)
- struts2 (6)
- spring (124)
- js (44)
- 算法 (65)
- linux (36)
- hibernate (7)
- 中间件 (78)
- 设计模式 (2)
- 架构 (275)
- 操作系统 (91)
- maven (35)
- tapestry (1)
- mybatis (9)
- MQ (101)
- zookeeper (18)
- 搜索引擎,爬虫 (208)
- 分布式计算 (45)
- c# (7)
- 抓包 (28)
- 开源框架 (45)
- 虚拟化 (12)
- mongodb (15)
- 计算机网络 (2)
- 缓存 (97)
- memcached (6)
- 分布式存储 (13)
- scala (5)
- 分词器 (24)
- spark (104)
- 工具 (23)
- netty (5)
- Mahout (6)
- neo4j (6)
- dubbo (36)
- canal (3)
- Hive (10)
- Vert.x (3)
- docker (115)
- 分布式追踪 (2)
- spring boot (5)
- 微服务 (56)
- 淘客 (5)
- mesos (67)
- php (3)
- etcd (2)
- jenkins (4)
- nginx (7)
- 区块链 (1)
- Kubernetes (92)
- 驾照 (1)
- 深度学习 (15)
- JGroups (1)
- 安全 (5)
- 测试 (16)
- 股票 (1)
- Android (2)
- 房产 (1)
- 运维 (6)
- 网关 (3)
最新评论
-
明兜3号:
部署落地+业务迁移 玩转k8s进阶与企业级实践技能(又名:Ku ...
Kubernetes系统常见运维技巧 -
q328965539:
牛掰啊 资料收集的很全面
HDFS小文件处理解决方案总结+facebook(HayStack) + 淘宝(TFS) -
guichou:
fluent挂载了/var/lib/kubelet/pods目 ...
kubernetes上部署Fluentd+Elasticsearch+kibana日志收集系统 -
xu982604405:
System.setProperty("java.r ...
jmx rmi 穿越防火墙问题及jmxmp的替代方案 -
大漠小帆:
麻烦问下,“获取每个Item相似性最高的前N个Item”,这个 ...
协同过滤推荐算法在MapReduce与Spark上实现对比
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; // 你好吗
由于时间问题。写的比较毛糙。先写到这了。。下午还要上班。。先小睡会。。。。。下次在写
相关推荐
以"Demo字节码的解析.xlsx"为例,我们可能看到一个简单的Java方法的字节码分析。例如,一个简单的`add(int a, int b)`方法可能包含以下字节码: ``` 0: iload_0 // 加载局部变量a到操作数栈 1: iload_1 // 加载局部...
**JAVA字节码操作库 BCEL** BCEL(Byte Code Engineering Library)是Java开发的一个重要工具,主要用于处理Java字节码。它为开发者提供了一种深入理解与操作Java类文件的底层机制,允许分析、创建、修改和优化字节...
`MyClass.class`是Java字节码文件,它是由`MyClass.java`源代码编译而来。这个过程包括将源代码中的字符串常量转换为字节码,这涉及到了String到Byte的转换。`input.txt`可能是一个文本文件,其内容可能需要在网络...
`jclasslib`则是一款图形化的Java字节码浏览器,主要用于解析和展示Java字节码文件(`.class`文件)的内容。它可以直观地显示字节码指令和常量池中的信息,并且提供了一定程度上的编辑功能,使得用户可以直接在图形...
### 探索Java虚拟机的心脏:字节码执行全解析 #### Java语言概览 Java自1995年由Sun Microsystems(现归Oracle所有)发布以来,已成为全球范围内广泛应用的编程语言。作为一种面向对象的语言,Java将现实世界中的...
- **解析:** Java源代码文件通常以`.java`为扩展名,在经过Java编译器(如javac)编译后会生成字节码文件,其扩展名为`.class`。字节码是一种中间代码形式,可以在任何支持Java虚拟机(JVM)的平台上运行而无需重新...
首先,APK实际上是一个ZIP格式的压缩包,包含了AndroidManifest.xml、资源文件、dex字节码等。传统的解析方法是通过读取ZIP文件并解析XML文件,但这对于经过加密或加壳处理的APK可能无效,因为它们可能对原始数据...
* 2:获得文件句柄当做是输入一个字节码流,需要对这个输入流进行读取 * 3:读取到输入流后,需要读取生成字节流 * 4:一行一行的输出。readline()。 * 备注:需要考虑的是异常情况 * @param filePath */...
Java字节码框架ASM是一个强大的库,它允许程序员在运行时动态生成和修改Java类和接口的字节码。ASM提供了对JVM字节码的底层访问,这使得开发者能够实现诸如AOP(面向切面编程)或者元编程等高级功能。 首先,我们...
"JAVAocr图像网页附加码解析读取"这个主题聚焦于如何利用Java编程语言和OCR(Optical Character Recognition,光学字符识别)技术来解析和读取网页中的附加码。附加码通常用于验证码,目的是防止自动化的机器人程序...
在Java中解析.dex文件是一项技术挑战,因为这涉及到理解Dalvik字节码和相关的文件结构。本篇将深入探讨如何进行这项工作。 首先,我们需要了解.dex文件的基本结构。一个.dex文件主要由以下几个部分组成: 1. **...
这些工具可能包括序列化/反序列化方法,用于将Java对象转换为适合Redis存储的字节码格式,以及压缩和解压缩方法。 - 这样的工具类能够帮助开发者更高效地与 Redis 交互,提高代码的可读性和可维护性,同时降低出错...
java agent的使用非常广泛,例如字节码插桩、bTrace、Arthas等。 在使用java agent时,需要在命令行输入java可以看到相应的参数,其中有和java agent相关的:-agentlib:[=<选项>] 加载本机代理库 ,例如 -agentlib:...
Java程序的执行由Java虚拟机(Java Virtual Machine,简称JVM)负责,它负责将Java的字节码(.class文件)解释执行。垃圾回收器(Garbage Collector)是JVM的一个组件,用于自动回收不再使用的对象所占的空间,而...
4. 解析MAC地址:从缓冲区中读取12字节,然后转换为`Long`或`String`表示形式。每个MAC地址由6个16进制数字组成,中间用冒号分隔。 5. 处理类型/长度字段:读取两个字节,根据值判断是长度还是协议类型。如果是协议...
`classes.dex`包含所有应用的字节码。`DexFile`类可以用于加载和解析这些文件,但需要额外的库如Apache Commons IO。 7. **获取签名信息**:APK文件在发布前会被签名,以验证其来源和完整性。`java.security.cert`...
【深入字节码 -- ASM 关键接口 ClassVisitor1】这篇技术文章主要探讨了ASM库在处理Java字节码时的核心接口ClassVisitor及其相关方法。ASM是一个强大的Java字节码操控和分析框架,常用于动态代理、字节码增强以及AOP...
4. **解析CDR文件**:在Java代码中,实例化ASN.1编解码器,然后读取CDR文件的字节流,使用编解码器将二进制数据转换为Java对象。以下是一个简化的示例: ```java ASN1InputStream asn1In = new ASN1InputStream...
在Java开发中,字节码框架ASM提供了一种强大的工具,允许程序员在运行时动态生成或修改类。ASM是一个底层的库,它直接操作Java字节码,这使得开发者能够在运行时改变类的行为或创建新的类。本文将深入探讨ASM框架的...
JVM(Java Virtual Machine)是Java程序的运行环境,负责解释字节码并执行程序。JDK(Java Development Kit)是开发工具包,包含JVM、编译器和其他开发工具。JRE(Java Runtime Environment)仅包含运行Java应用程序...