为什么字节码生成为
.annotation system Ldalvik/annotation/Throws;
value = {
Ljava/io/FileNotFoundException;
}
.end annotation
Run Code Online (Sandbox Code Playgroud)
而不是.throws Ljava/io/FileNotFoundException
throws FileNotFoundException如果一个方法在java代码的标头中声明?
我正在使用 ASM 代码迭代一个类而不操作任何字节代码。但是当我将 classwriter 转换为 bytearray(cw.toByteArray()) 时,我得到的方法代码太大了!例外。
谁能告诉我这是什么时候发生的..
我的代码片段如下---
InputStream in= new FileInputStream("D:/AshiqWorkspace/RandD/ByteCodeStudy/temp/GameManager.class");
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS|ClassWriter.COMPUTE_FRAMES);
ClassVisitor ca = null;
ca = new CustomClassNode(cw); // CustomClassNode class extends ClassNode implements Opcodes
cr.accept(ca, 0);
File outputDir=new File("D:/AshiqWorkspace/RandD/ByteCodeStudy/out");
outputDir.mkdirs();
DataOutputStream dout=new DataOutputStream(new FileOutputStream(new File(outputDir,"GameManager.class")));
dout.write(cw.toByteArray()); // on this line "method code too large exception coming"
Run Code Online (Sandbox Code Playgroud) 前段时间,我在将方法的现有代码嵌入 try-finally 块中询问如何使用 ASM 将方法的主体包装在 try-finally 块中。解决方案是访问 in 方法体开头的 try 块的标签,visitCode()并在访问具有返回操作码 in 的指令时完成 try-finally 块visitInsn()。我知道如果一个方法没有返回指令,则该解决方案将不起作用,如果该方法总是以异常情况离开则适用。
不过,我发现前一种解决方案有时也不适用于带有返回指令的方法。如果一个方法有多个返回指令,它将不起作用。原因是它生成了无效的字节码,因为在方法的开头添加了一个 try-finally 块,但完成了不止一个 try-finally 块。
通常(但可能取决于 javac 编译器),字节码方法包含单个返回指令,并且所有返回路径通过跳转到该指令结束。但是,使用 Eclipse 编译以下代码将导致带有两个返回指令的字节码:
public boolean isEven(int x) {
return x % 2 == 0;
}
Run Code Online (Sandbox Code Playgroud)
用Eclipse编译的字节码:
0: iload_1
1: iconst_2
2: irem
3: ifne 8
6: iconst_1
7: ireturn // javac compilation: goto 9
8: iconst_0
9: ireturn
Run Code Online (Sandbox Code Playgroud)
因此,我想知道包装方法代码的整个代码的正确方法是什么。
java instrumentation bytecode bytecode-manipulation java-bytecode-asm
当使用 拦截方法的实现时@Advice,是否可以访问局部变量?
Java字节码指令集提供了多种形式的dup指令。我无法理解这些说明和swap说明如何有用。编译时,哪些 Java 代码会使用这些指令生成字节码?
我想知道为什么Java字节码的行号不连续.
例如,在下面的getter的(未列出的)第2行和第3行中会发生什么?
public java.lang.String getX();
Code:
0: aload_0
1: getfield #2; //Field x:Ljava/lang/String;
4: areturn
Run Code Online (Sandbox Code Playgroud)
我正在使用ASM框架来处理字节码.当使用树API访问方法的代码时,我也会获得这些"隐藏"指令(但是使用操作码-1).我想知道它们的用途.
我试图通过异常捕获运行时异常。我能够捕获通常的方法退出事件。但是,控制从来没有伸进去opcode==Opcodes.ATHROW。
我想我在调用事件时做错了什么。
这是我的示例代码:
public void visitCode() {
// mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
// mv.visitLdcInsn("Entering method " + fQMethodName);
// mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream","println","(Ljava/lang/String;)V");
}
@Override
public void visitInsn(int opcode)
{
if (opcode == Opcodes.ATHROW)
{
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
mv.visitLdcInsn("Exiting on exception " );
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println",
"(Ljava/lang/String;)V");
}
super.visitInsn(opcode);
}
public void visitMethodInsn(int opcode, String owner, String name,
String desc) {
super.visitMethodInsn(opcode, owner, name, desc);
//
if (opcode == Opcodes.ATHROW)
{
mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
mv.visitLdcInsn("Exiting on exception " …Run Code Online (Sandbox Code Playgroud) 我使用ASM为while()语句生成字节代码.但是eclipse报道:
Exception in thread "main" java.lang.VerifyError: (class: show_cise_image, method: main signature: ([Ljava/lang/String;)V) Inconsistent stack height 2 != 1
at java.lang.Class.getDeclaredMethods0(Native Method)
..................
Run Code Online (Sandbox Code Playgroud)
我的字节码源代码:
show_cise_image {
boolean flag;
flag = true;
while(flag){
flag = false;
}
}
Run Code Online (Sandbox Code Playgroud)
生成上述代码的字节代码:
/ class version 51.0 (51)
// access flags 0x21
public class show_cise_image {
// access flags 0x8
static int v = 0
// access flags 0x8
static boolean flag = 0
// access flags 0x9
public static main(String[]) : void
L0
LINENUMBER 6 …Run Code Online (Sandbox Code Playgroud) 所以这是一个例子:
LocalVariableTable:
Start Length Slot Name Signature
0 133 0 this Lcom/my/class/Test;
2 131 1 a I
4 129 2 b I
7 126 3 i I
10 123 4 i2 I
16 117 5 o1 Ljava/lang/Integer;
31 102 6 o2 Ljava/lang/Integer;
Run Code Online (Sandbox Code Playgroud)
start和length是什么意思?为什么长度具有它的价值?为什么相同类型(整数)的长度不同?为什么长度可以更改,当我向类添加一些内容并重新编译它而不触及该特定的局部变量?
iload #index与其他3字节代码的区别.它们之间是否有任何性能差异.