Java反射 方法的反射 深入了解泛型

2021-08-03 03:55:13 字數 1913 閱讀 1319

invoke(物件,引數列表)

1、獲得類型別

class data = a.getclass();

2、獲得方法

- getmethod(「方法名」,可變引數(class)) 獲得自身和繼承的public方法

- getdeclaredmethod(「方法名」,可變引數(class)) 獲得自身的所有方法,不包括繼承的方法

method

print = data.getmethod

("print", new

class);

method

print2 = data.getdeclaredmethod

("print", new

class);

3、執行方法

invoke(物件obj,引數列表) 使用物件obj呼叫方法

print.invoke(a, 10, 20);

print2.invoke(a, new

string);

如果沒有引數,可以不寫:

method

print3 = data.getmethod

("print");

print3.invoke(a);

所謂泛型,是在編譯階段判斷變數型別是否滿足泛型要求。例如arraylist在編譯時如果add乙個int型別的變數肯定會出錯,但是,在編譯完成後,不同型別的泛型實際上是一樣的。如下:

arraylist list1 = new arraylist();

arraylist list2 = new arraylist();

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型別的add方法。原因是在編譯過後所有型別會被擦除。在arraylist的原始碼中用乙個object型別的陣列來儲存資料。編譯過變數會被儲存在object陣列中,所以add方法中的型別也會被轉化為object

transient object elementdata; // non-private to simplify nested class

access

個人理解,歡迎指正

C 反射的深入了解

assembly.load 的使用說明如下 並不是命名空間。常用的是程式集名稱,也就是dll的名稱 關於反射assembly.load 程式集 createinstance 命名空間.類 而不管在哪一層寫這段 其中的 程式集 讀取的實際是web層bin資料夾下的dll,也就是說你反射的類的程式集dl...

java反射 方法

取全部set方法 param t return public static final setget methods class t return methodset method知識 1.類方法 用static修飾的方法。由於類方法是屬於整個類的,所以類方法的方法體中不能有與類的物件有關的內容。即...

java中的構造方法的深入了解

很長時間對與構造方法沒有很深的認識,但看過一篇介紹他的文章後感覺恍然大悟,故而把文章整理了一下收藏至此。類的繼承機制使得子類可以使用父類的功能 即 並且子類也具有父類的型別。下面 介紹類在繼承關係上的初始化的順序問題。示例1 class superclass public class subclas...