Java学习日记----反射
------- android培訓、java培訓、期待與您交流! ----------
?
1 Class類
? 1.1 反射不是Java1.5的新特性,而是從1.2就有的特性,在以后學習到框架都要用到反射,要了解反射,就要先了解Class類.
? 1.2 Class代表一類事物,Java用類描述一類事物的共性這類事物有什么屬性,至于屬性的值,則由該類事物具體實例(對象)來確定,例如,在Java中的各個類,這也是一類事物,也可以用一個類來表示,這個類就是Class類.
? 1.3 一個Java類可以用一個Class對象來表示,一個類中的成份:成員變量,成員方法,構造方法,包等等信息,也可以用一個個Java類來描述.比如,一輛汽車是一個類,汽車中的發動機,變速箱也可以是一個個Java類,描述Java類的Class類顯然要提供一系列的方法,來獲取其中的變量,方法,構造方法,修飾符,包等信息,這些信息就是用相應的類的實例來表示,這些相應的類分別是:Field,Method,Constructor,Package等等.
? 1.4 字節碼
?? 當在程序中要使用到某一個類時,首先要從硬盤上將這個類的class文件的二進制代碼加???載到中,而后用這份二進制代碼創建一個個這個類的對象.
? 1.5 獲得字節碼對應的實例對象(Class對象)的方法
?? a> 類名.class
?? b> 對象的getClass()方法.
?? c> Class類有靜態方法forName(String name).
?? d>得到某個類的字節碼有兩種情況:
??? 1> 這個類的字節碼已經加載到內存中,直接找到返回就可以了.
??? 2> 這份字節碼不在內存中,于是用類加載器去加載,加載進來之后,緩存起來,同????時返回這份字節碼
? 1.6 做反射一般是用Class類有靜態方法forName(String name),因為在寫源程序時,還不知道類的???名字,在運行時,傳入一個字符串,里面包含有類的名字.
?? 有九個預定義的Class對象---->八種基本數據類型和void,在基本數據類型的包裝類中,???有一字段TYPE,就代表這個所包裝的基本類型的實例(Class對象).
2 Constructor類
? 2.1 Constructor類用于描述類中的構造方法.
? 2.2 Constructor類中的getConstructor()方法,用于獲取某個類的氖構造方法,如Class.forName("Java,lang.String").getgetConstructor()就是獲取String類中的所有構造方法.為了得到類中的某一構造方法,可以通過對應的構造方法的參數的類型的字節碼,如Class.forName("Java,lang.String").getgetConstructor(StringBuffer.class)就是獲???取了String類中的String(StringBuffer sb)構造方法
? 2.3 Constructor類中的newInstance()方法,可以創建對象,需要注意的是,編譯器只知道Constructor實例是代表某一個類的構造方法,而不知道是哪個類的構造方法,所以newInstance()方法返回的是Object對象.
? 2.4 在Class類中也有newInstance()方法,但只適用于空參數的構造方法,對于有參數的構造方法,只能獲取Constructor實例,再創建對象.
3 Field類
? 3.1 Field fieldy = dt.getClass().getField("y");
?? fieldy不是對象的變量y,而是類中的變量y,用fieldy去獲取某個對象中的y的值:當y被公有時(public修飾),fieldy.getField(Object obj);當y被私有時,先setAccessible(true),再fieldy.getField(Object obj),稱為"暴力反射"
?? 總:從個體中抽取共性部分,對所有實例都有用.
4 Method類
? 4.1 Method類是用于描述類中的方法的.
? 4.2 Method對象是通過Class類的getMethod()方法獲取的,但是getMethod()是獲取類中所有的方法對象,當要獲取某一個方法對象時,可以用getMethod(String methodName,Class<?>...parameterType)獲取.
? 4.3 通Method類中的invoke(Object obj,Object...args)方法,可以調用Method實例對象對應的方法,如果第一個參數為空,說明該對象所屬的方法是一個靜態方法.
? 4.3 對接收數組參數的成員方法進行反射
?? 啟動Java程序的main方法的參數是一個數組,String[] args,通過反射來調用這個方法時,如何為invoke()方法傳遞參數呢?按Java1.5的語法,整個數組是一個參數,按Java1.4的語法,數組中的每一個元素對應一個參數,把String[]傳給invoke()時,會按哪種方式處理呢?1.5肯定要兼容1.4的語法,會按1.4的語法進行處理,把數組打散成若干個單獨的參數,所以在給invoke()方法傳入參數時要注意,特別是接收數組參數的方法時.
? ?解決方案:
a> invoke(obj,new Object[]{new String[]{}});
??? b> invoke(obj,(Object)new String[]{});
?? a>方法是給數組包上一層皮,由編譯器去拆,b>方法是告訴編譯器,沒有皮了,可以不用拆.
?
5 數組的反射
? 5.1? int[] a1 = new int[3];
? ? int[] a2 = new int[4];
?? int[][] a3 = new int[3][2];
?? String [] a4 = new String[3];
??
?? a1.getClass() == a2.getClass()? //---true
? ? a1.getClass() == a3.getClass()? //---false
?? a1.getClass() == a4.getClass()? //---false
??
?? a1.getClass().getSuperclass().getName();? //----java.lang.Object
?? a4.getClass().getSuperclass().getName();? //----java.lang.Object
??
?? Object[] ibj1 = a1;? //---編譯通過不了
?? Object[] ibj3 = a3;? //---可以通過編譯
?? Object[] ibj4 = a4;? //---可以通過編譯
??
?? 從上可以看出,數組類型的父類是Object類,基本類型的一維數組僅能當作Object類用,而??基本類型的二維數組和引用類型的數組,不僅可以當作Object類用,還可以當作Object[]用
? 5.2 int[] a = new int[3];
?? 在反射中不能知道a是什么類型的數組的,因為a的反射后的類型是Class類型,可以通過??isArray()方法,判斷a是否是數組,再通過Array中的方法可以操作a.
轉載于:https://www.cnblogs.com/kftghai/archive/2012/12/08/2808188.html
總結
以上是生活随笔為你收集整理的Java学习日记----反射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 调用系统的照相机和图库
- 下一篇: 协议森林08 不放弃 (TCP协议与流通