多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > JAVA 反射

JAVA 反射

來源:程序員人生   發布時間:2015-05-27 08:17:10 閱讀次數:2417次

每一個類都會有1個Class對象,所有的類都是在首次使用時動態加載到JVM中。類加載器首先會檢查該類的Class對象是不是已被加載,如果還沒有被夾在。默許的類加載器就會根據類名查找.class文件,然后加載該類到內存。他就用來創建這個類的所有對象。


1. Class對象:

1.1 獲得1個類的Class對象: Class.forName();或使用類字面常量,這樣做在編譯期會接受檢查,不需要捕獲異常。不但普通的類,接口、數組及基本數據類型都有字面常量。類名.class

1.2  Class類。Class對象總是指向某個Class對象,可以制造類的實例,包括該類的靜態成員,作用于這些事例的所有方法代碼。JAVA 1.5之前使用的是普通類援用,1.5以后將類援用使用泛型語法變得更加具體。使用泛型語法的類以后,會讓編譯器強迫履行額外的類型檢查。為了使用泛化的Class援用時放松限制,可使用通配符“?”,表示任何事物。使用普通的Class援用時若果出錯,直到運行的時候才會被發現。創建Class援用,被限定為某種類型或該類型的任何子類型,可使用<? extends >

注:Class<?>和Class是等價的,Class<?>的好處是表示程序員就是自己選擇使用非具體的版本而不是由于忽視。

public class TestReflection { public static void main(String[] args) { Class intClass1 = int.class; Class doubleClass1 = double.class; Class<Integer> intClass2 = int.class;// Class<Integer> intClass2 = Integer.class; Class<Double> doubleClass2 = double.class; // intClass2 = double.class; // error Class<?> intClass3 = int.class; Class<? extends Number> int_double_class; int_double_class = int.class; int_double_class = double.class; } }

1.3  普通的Class和泛化的Class還有個區分,在使用泛型語法的Class時使用newInstance()返回該對象的確切類型,而普通的Class返回的是Object

class A{ public void print(){ System.out.println("AAA"); } } public class TestReflection { public static void main(String[] args) throws InstantiationException, IllegalAccessException { Class aClass1 = A.class; Object obj = aClass1.newInstance(); ((A)obj).print(); Class<A> aClass2 = A.class; A a2 = aClass2.newInstance(); a2.print(); } }

1.4  使用泛型語法取得父類的Class援用

class A{} class B extends A{} public class TestReflection { public static void main(String[] args) throws InstantiationException, IllegalAccessException{ Class<B> bClass = B.class; Class<? super B> aClass1 = bClass.getSuperclass(); // 不能寫成下面的情勢,雖然在編譯的時候在編譯起見就知道B的父類是A // Class<A> aClass2 = bClass.getSuperclass(); // error // 正由于上面的到的 aClass1 的含糊性,下面得到的返回值也不是精確類型而是Object Object aClassObj = aClass1.newInstance(); } }


2. 反射相干類 : java.lang.reflect包 包括了Field、Method、Constructor類,每一個類都實現了Menber接口。這些類對象都是在JVM運行時創建的。

反射機制提供了足夠的支持,使得能夠創建1個在編譯時完全未知的對象,并調用此對象的方法。

2.1 獲得類的構造函數、屬性和方法

class A{ private int i; public A (int x) { i = x; } public void print() { System.out.println("AAA"); } } public class TestReflection { public static void main(String[] args) throws InstantiationException, IllegalAccessException{ Class<?> aClass = null; try { aClass = Class.forName("reflection.A"); } catch (ClassNotFoundException e) { e.printStackTrace(); } System.out.println("------------類所有方法------------"); Method [] methods = aClass.getDeclaredMethods(); for (Method method : methods) { System.out.println(method.toString()); } System.out.println("------------類構造方法------------"); Constructor [] constructors = aClass.getDeclaredConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor.toString()); } System.out.println("------------類屬性------------"); // Field [] fields = aClass.getFields();//獲得public的 Field [] fields = aClass.getDeclaredFields(); //獲得public的 for (Field field : fields) { System.out.println(field.toString()); } } } //getFields()與getDeclaredFields()區分: //getFields()只能訪問類中聲明為公有的字段,getDeclaredFields()能訪問類中所有的字段 //getMethods()與getDeclaredMethods()區分: //getMethods()只能訪問類中聲明為公有的方法,能訪問從其它類繼承來的公有方法,getDeclaredFields()能訪問類中所有的字段,不能訪問從其它類繼承來的方法 //getConstructors()只能訪問類中聲明為public的構造函數,getDeclaredConstructors()能訪問類中所有的構造函數

2.2 創建對象

class A{ private int i; public A(){} private A (int x) { i = x; } public void print() { System.out.println("AAA"); } public int getI() { return i; } public void setI(int i) { this.i = i; } } public class TestReflection { public static void main(String[] args){ try { Class<A> aClass = A.class; //創建對象的兩種方式 // 1. Class.newInstance aClass.newInstance();// 必須有默許的構造函數 // 2. Constructor.newInstance Constructor<A> intConstructors = aClass.getDeclaredConstructor(int.class); // new Class<?> []{int.class} intConstructors.setAccessible(true); A a = intConstructors.newInstance(100); System.out.println(a.getI()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

2.3 訪問類屬性 1般用來修改源碼中類成員的值

<pre name="code" class="java">class A{ private static boolean isOpen = false; public static boolean isOpen() { return isOpen; } } public class TestReflection { public static void main(String[] args){ try { System.out.println(A.isOpen()); Field openField = A.class.getDeclaredField("isOpen"); openField.setAccessible(true); openField.setBoolean(new A(), true); System.out.println(A.isOpen()); } catch (Exception e) { e.printStackTrace(); } } }


2.4 調用函數

<pre name="code" class="java">class A{ private void print() { System.out.println("AAA"); } } public class TestReflection { public static void main(String[] args){ try { A a = new A(); Class<A> aClass = (Class<A>) a.getClass(); aClass.getDeclaredMethod("print"); Method printMethod = aClass.getDeclaredMethod("print");//Method printMethod = aClass.getDeclaredMethod("print", new Class<?>[]{}); printMethod.setAccessible(true); printMethod.invoke(a); } catch (Exception e) { e.printStackTrace(); } } }


注:利用反射調用私有屬性、構造函數或方法時要設置Accessible屬性為true。










生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 天码毛片一区二区三区入口 | 国产一区二区三区四区在线观看 | 日韩欧美亚 | 国产精品国产亚洲精品不卡 | 一区二区视频在线观看高清视频在线 | 欧美成人午夜在线全部免费 | 国产成人免费永久播放视频平台 | 亚洲欧美综合国产精品一区 | 九九精品视频在线播放8 | 国内精品伊人久久 | 黄色片xxxxx| 中国精品自拍 | 欧美大陆日韩一区二区三区 | 亚洲小说区图片区 | 亚洲欧美综合国产精品一区 | 亚洲wwwwww| 久久久久综合国产 | 亚洲欧美经典 | 欧美一区二区三区性 | 国产性夜夜春夜夜爽30 | 小说区亚洲区 | 欧美videos13_14| www.黄色免费网站 | 亚洲精品福利一区二区 | 一个色在线 | 亚洲精品成人一区 | 欧美一级大黄特黄毛片视频 | 99热精品成人免费观看 | 91福利影院 | 欧美不卡一区二区三区免 | 国产在线精品福利91香蕉 | xxx日本护士www| 91手机看片国产福利精品 | 毛片在线播放观看日本 | 天堂最新版www在线观看 | 性国产videofree极品 | 波多野结衣亚洲一区二区三区 | 成人国产在线视频在线观看 | 久久久久日韩精品免费观看网 | a天堂v| 微信影院手机在线播放 |