反射中的Constructor和數組反射
一、反射中的Constructor
Constructor類代表某個類中的一個構造方法
Constructor 翻譯過來的意思是"構造函數",它是用來描述一個類中的構造函數的。JDK幫助文檔的解釋--->Constructor
提供關於類的單個構造方法的信息以及對它的訪問權限。
現在我有一個MyConstructor類,用反射分別打印出1,2,3.
public class MyConstructor {// --------------------------------------1
public MyConstructor(){
System.out.println("1");
}
public MyConstructor(int i){//--------------------------------------2
System.out.println("2");
}
public MyConstructor(int i,String s){//---------------------------3
System.out.println("3");
}
}
下麵我們現在打印出一個1
public static void main(String[] args) throws Exception{
//截的圖是JDK幫助文檔裏麵的解釋
Constructor myConstructor1 = MyConstructor.class.getConstructor();//這裏得到的是標記為1的構造函數(相關知識點方法的重載)
myConstructor1.newInstance();
//上麵的2句話輸出結果為1.
Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class);//這裏得到的是標記為2的構造函數(相關知識點方法的重載)
//開始由於受到反射invoke()的思想,並且沒有看幫助文檔對newInstance()的解釋,然後我直接寫了下麵的語句
myConstructor1.newInstance(new MyConstructor());//new MyConstructor()我的意思是傳帶有myConstructor1的構造函數方法的對象給它調用(這裏不懂的同學可以看幫 //助文檔Method類中invoke()方法的解釋),好嘛這裏是我弄混淆了
寫成這樣也是錯的myConstructor1.newInstance(int.class);
//輸出結果為
//argument type mismatch翻譯過來的意思是:參數類型不匹配
// 最後寫成這樣就對了
myConstructor1.newInstance(0);
//執行輸出的結果為2.
//打印1和打印2都寫出來了,想必大家打印出3就不難了。
Constructor myConstructor1 = MyConstructor.class.getConstructor(int.class,String.class);//這裏得到的是標記為3的構造函數(相關知識點方法的重載)
myConstructor1.newInstance(0,"a");
//執行輸出的結果為3
}
二、數組反射
在jdk幫助文檔中的Class介紹有這樣的話:
什麼意思呢?意思就是說如果有2個數組對象,它們具有相同的元素類型和維數的話,那它們的class(在內存中的字節碼)也是相同的。
示例代碼一:
public static void main(String[] args){
int [] a1 = new int[3];
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[3];
System.out.println(a1==a2);//類型相等,維度相等
//System.out.println(a1==a4);//類型不等,維度相等--------這句編譯報錯
//System.out.println(a1==a3);//類型相等,維度不等--------這句編譯報錯
}
輸出為:false
咦~~~怎麼會是false呢,明明類型相等,維度相等,那為什麼還是false呢?後麵突然發現a1 == a2比的是對象,它們的內容不相等,所以為false。最後改成下麵的正確代碼:
public static void main(String[] args){
int [] a1 = new int[3];
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[3];
System.out.println(a1.getClass()==a2.getClass());//類型相等,維度相等
System.out.println(a1.getClass()==a4.getClass());//類型不等,維度相等
System.out.println(a1.getClass()==a3.getClass());//類型相等,維度不等
}
這裏大家在看下麵的結果前可以自己先想想
輸出結果為:
true
false
false
在這裏有個小插曲下麵2張圖大家對比下
圖一:
圖二:
細心的你一定發現了哈,二張圖的內容都是一樣的,毫無區別,那為什麼圖二中的內容有編譯不通過的呢?
現在我隻能告訴你圖一的JDK是1.4的,而圖二的JDK是1.6的,關於JDk1.5有興趣的朋友可以改來試試哈,至於為什麼會這樣,具體原因我也說不出來,因為我不知道,嘿嘿~~~~(拿別人的回答來給大家參考參考吧------->“這是編譯報錯,你用的比以前的東西高級了,後麵兩個明顯因為是類型都不對,答案是false的就直接編譯就報錯了再說明白點,編譯器版本高了聰明了,覺得這種問題低級所以不想讓你編譯通過了”對這解釋感覺神忽忽的--!)
好奇的人會嚐試的運行這個代碼:System.out.println(a1.getClass().getName());輸入結果為:[I,什麼意思呢?[:代表是數組,I:代表是int類型。與之相關的介紹在JDK幫助文檔裏麵有解說。
System.out.println(a3.getClass().getName());//int [][] a3 = new int[2][3];
System.out.println(void.class.getName());
上麵兩句分別輸出:
[[I
void
如果是String[][][][][] test = new String[1][2][3][4][5];會輸出什麼?
public static void main(String[] args){
int [] a1 = new int[3];
int [] a2 = new int[4];
int [][] a3 = new int[2][3];
String[] a4 = new String[3];
System.out.println(a1.getClass().getSuperclass().getName());//getSuperclass()得到父類的class
System.out.println(a4.getClass().getSuperclass().getName());
//這2句話輸出分別為java.lang.Object和java.lang.Object(表明a1和a4的父類都一樣)
//所以
Object aObj1 = a1;//裏氏替換原則
Object aObj2 = a4;//裏氏替換原則
//下麵代碼回報編譯異常
Object[] aObj3 = a1;//int [] a1 = new int[3];理解為有一個int[]數組,裏麵裝的是int類型,int類型不屬於Object
Object[] aObj4 = a3;//int [][] a3 = new int[2][3];理解為有一個int[]數組,裏麵裝的是int[]類型,int[]類型屬於Object
Object[] aObj5 = a4;//String[] a4 = new String[3];理解為有一個String[]數組,裏麵裝的是String類型,String類型屬於Object
}
用反射的方式操作數組
我有一個方法public static void print(Object obj){},這方法是用來打印東西的方法,你傳一個對象給我,我就給你打印,這時候問題出現了,你會不會傳一個數組給我呢?答案是會的,但是我又怎麼知道你傳的是數組呢?這時候數組的反射有派上用場了
上代碼:
/**
* 打印對象
* @param obj 你傳來的任何對象,如果是數組,打印裏麵的每一個元素
*/
public static void printObject(Object obj){
Class clazz = obj.getClass();
//true:代表是數組,false:代表不是數組
if (clazz.isArray()) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
System.out.println("另一種獲取的方法");
Object[] tempObj = (Object[]) obj;
for (Object object : tempObj) {
System.out.println(object);
}
}else{
System.out.println(obj);
}
}
public static void main(String[] args){
printObject(a4);
printObject("hahaha");
}
輸出結果:
a
b
c
另一種獲取的方法
a
b
c
hahaha
有一個Object[] a = new Object[]{"a",1};這時候您是說不清這個a是什麼類型的,說是int它裏麵有String,說是String它裏麵有int,但是可以知道a[0]是什麼類型的,a[1]是什麼類型的,a[0].getClass().getName();
最後更新:2017-04-03 14:54:08