Java字節碼與反射機制

    字節碼(Byte Code)是Java語言跨平臺特性的重要保障,也是反射機制的重要基礎。通過反射機制,我們不僅能看到一個類的屬性和方法,還能在一個類裏調用另外一個類的方法,但前提是我們得有相關類的字節碼文件(也就是.class文件)。

1 字節碼和.class文件

    當我們編寫好以.java爲擴展名的文件後,如果它能被運行(比如其中包含main函數),那麼我們能通過點擊MyEclipse裏的運行按鈕運行這個.java文件。

    但此時,MyEclipse向我們隱藏了一個關鍵步驟:它首先是把.java文件編譯成擴展名是.class的字節碼文件,隨後,Java的虛擬機(JVM)是在當前的操作系統上(比如window 10)上運行這個.class文件。

    也就是說,.java文件是得被編譯成.class文件後才能運行,更爲神奇的是,大家在window 7系統裏編譯好的.class文件能直接在Linux系統裏運行(當然這個系統裏得有Java運行環境),這就是java的跨平臺裏特性,也叫能“一處編譯到處運行”。

    有些偏題了,回到反射這個話題上,只要我們能得到.class這個字節碼文件,那麼通過反射機制我們不僅能看到這個.class所對應java文件裏的屬性方法等信息,而且還能調用它所對應java文件裏的方法。

2 Class類(C是大寫)是反射實現的語法基礎

    通過某些工具,我們能打開.class文件,並也能看到其中包含的屬性和方法,但我們不能直接針對.class文件編程,我們得使用Class(C是大寫)這個類。

    Class類的全稱是java.lang.Class,當一個類或接口(總之是java文件被編譯後的class文件)被裝入到Java虛擬機(JVM)時便會產生一個與和它相關聯的java.lang.Class對象,在反射部分的代碼裏,我們一般是通過這個Class來訪問和使用目標類的屬性和方法。

    通過反射機制,能從.class文件裏看到指定類的屬性,比如屬性的修飾符,屬性和類型和屬性的變量名。通過下面的ReflectionReadVar.java,我們看演示下具體的做法。    

1	import java.lang.reflect.Field;
2	import java.lang.reflect.Modifier;
3	class MyValClass{
4		private int val1;
5		public String val2;
6		final protected String val3 = "Java";
7	}

    我們在第3行定義了一個MyValCalss的類,並在第4到第6行裏,定義了三個屬性變量。    

8	public class ReflectionReadVar {
9		public static void main(String[] args) {
10			Class<MyValClass> clazz = MyValClass.class;
11			//獲取這個類的所有屬性
12	        Field[] fields = clazz.getDeclaredFields();
13		    for(Field field : fields) {
14		    	   //輸出修飾符	    	   System.out.print(Modifier.toString(field.getModifiers()) + "\t");
15		    	   //輸出屬性的類型
16		       System.out.print(field.getGenericType().toString() + "\t");
17		    	   //輸出屬性的名字
18		    	   System.out.println(field.getName());
19		      }
20		}
21	}

     在main函數的第10行裏,通過MyValClass.class,得到了Class<MyValClass>類型的變量clazz,在這個變量中,存儲了MyValClass這個類的一些信息。

    在第12行裏,通過了clazz.getDeclaredFields()方法得到了MyValClass類裏的所有屬性的信息,並把這些屬性的信息存入到Field數組類型的fields變量裏。

    通過了第13行的for循環依次輸出了這些屬性信息。具體來講,通過第14行的代碼輸出了該屬性的修飾符,通過第16行的代碼輸出了該屬性的類型,通過第18行的代碼輸出了該屬性的變量名。這段代碼的輸出如下,從中我們能看到各屬性的信息。

  1. private    int val1
  2. public class java.lang.String   val2
  3. protected final   class java.lang.String   val3
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章