㈠ java注解是怎么实现的
写一个使用该注解的类:
import java.io.IOException;
/**
* Created by Administrator on 2015/1/18.
*/
@TestAnnotation(count = 0x7fffffff)
public class TestMain {
public static void main(String[] args) throws InterruptedException, NoSuchFieldException, IllegalAccessException, IOException {
TestAnnotation annotation = TestMain.class.getAnnotation(TestAnnotation.class);
System.out.println(annotation.count());
System.in.read();
}
}
反编译一下这段代码:
Classfile /e:/workspace/intellij/SpringTest/target/classes/TestMain.class
Last modified 2015-1-20; size 1006 bytes
MD5 checksum
Compiled from "TestMain.java"
public class TestMain
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #10.#34 // java/lang/Object."<init>":()V
#2 = Class #35 // TestMain
#3 = Class #36 // TestAnnotation
#4 = Methodref #37.#38 // java/lang/Class.getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
#5 = Fieldref #39.#40 // java/lang/System.out:Ljava/io/PrintStream;
#6 = InterfaceMethodref #3.#41 // TestAnnotation.count:()I
#7 = Methodref #42.#43 // java/io/PrintStream.println:(I)V
#8 = Fieldref #39.#44 // java/lang/System.in:Ljava/io/InputStream;
#9 = Methodref #45.#46 // java/io/InputStream.read:()I
#10 = Class #47 // java/lang/Object
#11 = Utf8 <init>
#12 = Utf8 ()V
#13 = Utf8 Code
#14 = Utf8 LineNumberTable
#15 = Utf8 LocalVariableTable
#16 = Utf8 this
#17 = Utf8 LTestMain;
#18 = Utf8 main
#19 = Utf8 ([Ljava/lang/String;)V
#20 = Utf8 args
#21 = Utf8 [Ljava/lang/String;
#22 = Utf8 annotation
#23 = Utf8 LTestAnnotation;
#24 = Utf8 Exceptions
#25 = Class #48 // java/lang/InterruptedException
#26 = Class #49 // java/lang/NoSuchFieldException
#27 = Class #50 // java/lang/IllegalAccessException
#28 = Class #51 // java/io/IOException
#29 = Utf8 SourceFile
#30 = Utf8 TestMain.java
#31 = Utf8 RuntimeVisibleAnnotations
#32 = Utf8 count
#33 = Integer 2147483647
#34 = NameAndType #11:#12 // "<init>":()V
#35 = Utf8 TestMain
#36 = Utf8 TestAnnotation
#37 = Class #52 // java/lang/Class
#38 = NameAndType #53:#54 // getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
#39 = Class #55 // java/lang/System
#40 = NameAndType #56:#57 // out:Ljava/io/PrintStream;
#41 = NameAndType #32:#58 // count:()I
#42 = Class #59 // java/io/PrintStream
#43 = NameAndType #60:#61 // println:(I)V
#44 = NameAndType #62:#63 // in:Ljava/io/InputStream;
#45 = Class #64 // java/io/InputStream
#46 = NameAndType #65:#58 // read:()I
#47 = Utf8 java/lang/Object
#48 = Utf8 java/lang/InterruptedException
#49 = Utf8 java/lang/NoSuchFieldException
#50 = Utf8 java/lang/IllegalAccessException
#51 = Utf8 java/io/IOException
#52 = Utf8 java/lang/Class
#53 = Utf8 getAnnotation
#54 = Utf8 (Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
#55 = Utf8 java/lang/System
#56 = Utf8 out
#57 = Utf8 Ljava/io/PrintStream;
#58 = Utf8 ()I
#59 = Utf8 java/io/PrintStream
#60 = Utf8 println
#61 = Utf8 (I)V
#62 = Utf8 in
#63 = Utf8 Ljava/io/InputStream;
#64 = Utf8 java/io/InputStream
#65 = Utf8 read
{
public TestMain();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTestMain;
public static void main(java.lang.String[]) throws java.lang.InterruptedException, java.lang.NoSuchFieldException, java.lang.IllegalAccessException, java.io.IOException;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: ldc #2 // class TestMain
2: ldc #3 // class TestAnnotation
4: invokevirtual #4 // Method java/lang/Class.getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
7: checkcast #3 // class TestAnnotation
10: astore_1
11: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
14: aload_1
15: invokeinterface #6, 1 // InterfaceMethod TestAnnotation.count:()I
20: invokevirtual #7 // Method java/io/PrintStream.println:(I)V
23: getstatic #8 // Field java/lang/System.in:Ljava/io/InputStream;
26: invokevirtual #9 // Method java/io/InputStream.read:()I
29: pop
30: return
LineNumberTable:
line 10: 0
line 11: 11
line 12: 23
line 13: 30
LocalVariableTable:
Start Length Slot Name Signature
0 31 0 args [Ljava/lang/String;
11 20 1 annotation LTestAnnotation;
Exceptions:
throws java.lang.InterruptedException, java.lang.NoSuchFieldException, java.lang.IllegalAccessException, java.io.IOException
}
SourceFile: "TestMain.java"
RuntimeVisibleAnnotations:
0: #23(#32=I#33)
最后一行的代码说明,注解`TestAnnotation`的属性设置是在编译时就确定了的。(对属性的说明在[这里][1])。
然后,运行上面的程序,通过CLHSDB在eden区找到注解实例,
hsdb> scanoops 0x00000000e1b80000 0x00000000e3300000 TestAnnotation
0x00000000e1d6c360 com/sun/proxy/$Proxy1
类型`com/sun/proxy/$Proxy1`是jdk动态代理生成对象时的默认类型,其中
`com.sun.proxy`是默认的包名,定义于`ReflectUtil`类的`PROXY_PACKAGE`字段中。代理类名`$PROXY1`
包含两部分,其中前缀`$PROXY`是jdk种默认的代理类类名前缀(参见`java.lang.reflect.Proxy`类的javadoc),
后的1是自增的结果。
㈡ 错误: 找不到或无法加载主类 sun.jvm.hotspot.ui.AnnotatedMemoryPanel
1.下载JDK并安装
JDK默认安装在C:Program FilesJavajdk1.8.0_05目录下(我安装版本和目录)
2.环境变量配置(请按顺序来设置)
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_05
CLASSPATH=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;
PATH=.;%JAVA_HOME%\bin;
JAVA_HOME设置(win7下):
计算机右键"属性"-"高级系统设置"-"高级"-"环境变量"-"(系统变量s下)新建"
变量名:【JAVA_HOME】,变量值【C:\Program Files\Java\jdk1.8.0_05】
CLASSPATH设置:
计算机右键"属性"-"高级系统设置"-"高级"-"环境变量"-"(系统变量s下)新建"
变量名:【CLASSPATH】
变量值:【.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;】
PATH设置(path已经有不用新建,找到path点击编辑即可)
计算机右键"属性"-"高级系统设置"-"高级"-"环境变量"-"(系统变量s下)找到path编辑"
在变量值后面添加【.;%JAVA_HOME%\bin;】
3.在C盘目录下新建【java】文件夹,文件夹下新建【HelloWorld.java】文件,用记事本打开复制以下代码并保存:
public class HelloWorld
{
public static void main(String args[])
{
System.out.println("Hello World");
}
}
4.打开CMD窗口编译解析,【cd c:\java】切换到java文件夹下,编译执行打印"HelloWorld".
㈢ Java有字节码级别的单步动态调试工具吗
作者:RednaxelaFX
链接:https://www.hu.com/question/36051329/answer/65735192
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
例如这个?Bytecode Visualizer不过题主想要的功能多半还得在上面这个工具的基础之上再扩展一下。我自己做字节码层面调试的时候通常就直接用JDK自带的jdb命令行调试器,支持字节码层面调试,不过用起来当然没有带GUI的工具那么直观咯。之前写的一篇博文里有用jdb举过例子:借HSDB来探索HotSpot VM的运行时数据。虽然那篇没有提到,但其实用 stepi 和 nexti 命令就可以在jdb里做字节码层面的单步调试(普通的基于代码行的单步调试命令则是 step 和 next,少个i后缀)。jdb的字节码层面调试最让人不爽的一点就是它不能在任意字节码指令上设断点。我以前用jdb都是只能设方法入口断点然后不断的 stepi 单步走到我要的指令上。这对稍微复杂一点的调试工作来说就极其纱布。jdb间接基于JVMTI实现,而JVMTI的SetBreakpoint函数其实是可以在任意字节码指令上设断点的,只要GetJLocationFormat返回1(JVMTI_JLOCATION_JVMBCI)。jdb直接基于的是JVMTI之上的Java层包装,JDI。它的本体入口在这里:jdk7u/jdk7u/jdk: e228aaace9c9 src/share/classes/com/sun/tools/example/debug/tty/TTY.java而断点相关的部分在这里:jdk7u/jdk7u/jdk: e228aaace9c9 src/share/classes/com/sun/tools/example/debug/tty/BreakpointSpec.java鼓捣鼓捣这里就能让它支持字节码指令层面(BCI,bytecode index)的断点…
㈣ java注解是怎么实现的
写一个使用该注解的类:
import java.io.IOException;
/**
* Created by Administrator on 2015/1/18.
*/
@TestAnnotation(count = 0x7fffffff)
public class TestMain {
public static void main(String[] args) throws InterruptedException, NoSuchFieldException, IllegalAccessException, IOException {
TestAnnotation annotation = TestMain.class.getAnnotation(TestAnnotation.class);
System.out.println(annotation.count());
System.in.read();
}
}
反编译一下这段代码:
Classfile /e:/workspace/intellij/SpringTest/target/classes/TestMain.class
Last modified 2015-1-20; size 1006 bytes
MD5 checksum
Compiled from "TestMain.java"
public class TestMain
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #10.#34 // java/lang/Object."<init>":()V
#2 = Class #35 // TestMain
#3 = Class #36 // TestAnnotation
#4 = Methodref #37.#38 // java/lang/Class.getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
#5 = Fieldref #39.#40 // java/lang/System.out:Ljava/io/PrintStream;
#6 = InterfaceMethodref #3.#41 // TestAnnotation.count:()I
#7 = Methodref #42.#43 // java/io/PrintStream.println:(I)V
#8 = Fieldref #39.#44 // java/lang/System.in:Ljava/io/InputStream;
#9 = Methodref #45.#46 // java/io/InputStream.read:()I
#10 = Class #47 // java/lang/Object
#11 = Utf8 <init>
#12 = Utf8 ()V
#13 = Utf8 Code
#14 = Utf8 LineNumberTable
#15 = Utf8 LocalVariableTable
#16 = Utf8 this
#17 = Utf8 LTestMain;
#18 = Utf8 main
#19 = Utf8 ([Ljava/lang/String;)V
#20 = Utf8 args
#21 = Utf8 [Ljava/lang/String;
#22 = Utf8 annotation
#23 = Utf8 LTestAnnotation;
#24 = Utf8 Exceptions
#25 = Class #48 // java/lang/InterruptedException
#26 = Class #49 // java/lang/NoSuchFieldException
#27 = Class #50 // java/lang/IllegalAccessException
#28 = Class #51 // java/io/IOException
#29 = Utf8 SourceFile
#30 = Utf8 TestMain.java
#31 = Utf8 RuntimeVisibleAnnotations
#32 = Utf8 count
#33 = Integer 2147483647
#34 = NameAndType #11:#12 // "<init>":()V
#35 = Utf8 TestMain
#36 = Utf8 TestAnnotation
#37 = Class #52 // java/lang/Class
#38 = NameAndType #53:#54 // getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
#39 = Class #55 // java/lang/System
#40 = NameAndType #56:#57 // out:Ljava/io/PrintStream;
#41 = NameAndType #32:#58 // count:()I
#42 = Class #59 // java/io/PrintStream
#43 = NameAndType #60:#61 // println:(I)V
#44 = NameAndType #62:#63 // in:Ljava/io/InputStream;
#45 = Class #64 // java/io/InputStream
#46 = NameAndType #65:#58 // read:()I
#47 = Utf8 java/lang/Object
#48 = Utf8 java/lang/InterruptedException
#49 = Utf8 java/lang/NoSuchFieldException
#50 = Utf8 java/lang/IllegalAccessException
#51 = Utf8 java/io/IOException
#52 = Utf8 java/lang/Class
#53 = Utf8 getAnnotation
#54 = Utf8 (Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
#55 = Utf8 java/lang/System
#56 = Utf8 out
#57 = Utf8 Ljava/io/PrintStream;
#58 = Utf8 ()I
#59 = Utf8 java/io/PrintStream
#60 = Utf8 println
#61 = Utf8 (I)V
#62 = Utf8 in
#63 = Utf8 Ljava/io/InputStream;
#64 = Utf8 java/io/InputStream
#65 = Utf8 read
{
public TestMain();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 7: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTestMain;
public static void main(java.lang.String[]) throws java.lang.InterruptedException, java.lang.NoSuchFieldException, java.lang.IllegalAccessException, java.io.IOException;
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: ldc #2 // class TestMain
2: ldc #3 // class TestAnnotation
4: invokevirtual #4 // Method java/lang/Class.getAnnotation:(Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
7: checkcast #3 // class TestAnnotation
10: astore_1
11: getstatic #5 // Field java/lang/System.out:Ljava/io/PrintStream;
14: aload_1
15: invokeinterface #6, 1 // InterfaceMethod TestAnnotation.count:()I
20: invokevirtual #7 // Method java/io/PrintStream.println:(I)V
23: getstatic #8 // Field java/lang/System.in:Ljava/io/InputStream;
26: invokevirtual #9 // Method java/io/InputStream.read:()I
29: pop
30: return
LineNumberTable:
line 10: 0
line 11: 11
line 12: 23
line 13: 30
LocalVariableTable:
Start Length Slot Name Signature
0 31 0 args [Ljava/lang/String;
11 20 1 annotation LTestAnnotation;
Exceptions:
throws java.lang.InterruptedException, java.lang.NoSuchFieldException, java.lang.IllegalAccessException, java.io.IOException
}
SourceFile: "TestMain.java"
RuntimeVisibleAnnotations:
0: #23(#32=I#33)
最后一行的代码说明,注解`TestAnnotation`的属性设置是在编译时就确定了的。(对属性的说明在[这里][1])。
然后,运行上面的程序,通过CLHSDB在eden区找到注解实例,
hsdb> scanoops 0x00000000e1b80000 0x00000000e3300000 TestAnnotation
0x00000000e1d6c360 com/sun/proxy/$Proxy1
类型`com/sun/proxy/$Proxy1`是jdk动态代理生成对象时的默认类型,其中
`com.sun.proxy`是默认的包名,定义于`ReflectUtil`类的`PROXY_PACKAGE`字段中。代理类名`$PROXY1`
包含两部分,其中前缀`$PROXY`是jdk种默认的代理类类名前缀(参见`java.lang.reflect.Proxy`类的javadoc),
后的1是自增的结果。