㈠ 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是自增的結果。