Java反射—方法的反射、深入瞭解泛型
版權宣告:本文為博主原創文章,轉載請註明出處。 https://blog.csdn.net/twilight_karl/article/details/73848996
方法的反射
invoke(物件,引數列表)
1、獲得類型別 Class data = a.getClass();
2、獲得方法
– getMethod(“方法名”,可變引數(Class[])) 獲得自身和繼承的public方法
– getDeclaredMethod(“方法名”,可變引數(Class[])) 獲得自身的所有方法,不包括繼承的方法
Method print = data.getMethod("print", new Class[]{int.class,int.class});
Method print2 = data.getDeclaredMethod("print", new Class[]{String.class,String.class});
3、執行方法
invoke(物件obj,引數列表) 使用物件obj呼叫方法
print.invoke(a, 10, 20);
print2.invoke(a, new String[]{"hello","world"});
如果沒有引數,可以不寫:
Method print3 = data.getMethod("print");
print3.invoke(a);
通過反射了解泛型的本質
所謂泛型,是在編譯階段判斷變數型別是否滿足泛型要求。例如ArrayList<Stirng> 在編譯時如果add一個int型別的變數肯定會出錯,但是,在編譯完成後,不同型別的泛型實際上是一樣的。如下:
ArrayList list1 = new ArrayList();
ArrayList<String> list2 = new ArrayList<String>();
Class c1 = list1.getClass();
Class c2 = list2.getClass();
System.out.println(c1 == c2); // true
說明不同型別的泛型在編譯後是一樣的,泛型只是幫助判斷變數型別的一種機制。
String型別的泛型,只能加入String型別的變數,所以集合中儲存的變數原本都是String型別。而Object型別的泛型可以加入任意型別的變數,所有變數都會被轉換為Object型別後儲存,所以在去變數時,需要手動的將Object型別強制轉換為指定的型別。
反射機制是在編譯之後完成的。所以可以利用反繞過泛型的編譯:
Method add = c2.getMethod("add", Object.class);
add.invoke(list2, 100);
System.out.println(list2.size()); // 1
System.out.println(list2); // [100]
上面的例子在String型別的泛型集合中加入了整形變數,說明泛型的型別檢查是在執行之前進行的。編譯過後不會有泛型的型別檢查,所以不會報錯。另外我在編寫的過程中還發現一個細節:
Method add = c2.getMethod("add", String.class);
上面這行程式碼會報錯,c2是ArrayList<String>的類型別。一個String型別的泛型集合卻無法獲得String型別的add方法。原因是在編譯過後所有型別會被擦除。在ArrayList的原始碼中用一個Object型別的陣列來儲存資料。編譯過變數會被儲存在Object陣列中,所以add方法中的型別也會被轉化為Object
transient Object[] elementData; // non-private to simplify nested class access
個人理解,歡迎指正
參考資料:反射
相關文章
- 【Java反射】Java 泛型基礎Java反射泛型
- 如何用反射呼叫泛型類的方法反射泛型
- Java反射給泛型集合賦值Java反射泛型賦值
- 你瞭解Java反射嗎?Java反射
- 關於Java中泛型、反射和註解的掃盲篇Java泛型反射
- 一篇瞭解Java反射Java反射
- Java進階 | 泛型機制與反射原理Java泛型反射
- Java中反射的概述及瞭解ClassLoaderJava反射
- Java 方法的反射Java反射
- 8.集合、泛型、列舉、註解、反射泛型反射
- Go Internals: Go 反射 vs Java 泛型 vs cpp 模板Go反射Java泛型
- 深入理解Java反射Java反射
- Java反射與hook混用反射某支付的方法Java反射Hook
- java反射構建物件和方法的反射呼叫Java反射物件
- C# 透過反射(Reflection)呼叫不同名泛型方法C#反射泛型
- 通過反射認識泛型的本質反射泛型
- 深入理解Java反射(一)Java反射
- Go中泛型和反射比較指南Go泛型反射
- Java反射-註解Java反射
- Java 反射詳解Java反射
- java反射全解Java反射
- java反射詳解Java反射
- Java基礎——深入理解反射Java反射
- 一文帶你瞭解Java反射機制Java反射
- 你必須瞭解的反射——反射來實現實體驗證反射
- Java程式設計:一步步教你如何深入瞭解神秘的Java反射機制Java程式設計反射
- 反射的深入淺出反射
- Java反射與註解Java反射
- Java註解和反射Java反射
- Java 註解和反射Java反射
- Java的反射Java反射
- Java反射—初探反射基礎Java反射
- Java 泛型,你瞭解型別擦除嗎?Java泛型型別
- 【Java 反射學習】Java 反射基礎Java反射
- [Java 反射學習] Java 反射基礎Java反射
- Java註解與反射的使用Java反射
- Java 型別資訊詳解和反射機制Java型別反射
- Java 反射Java反射
- Java——反射Java反射