java中不通過new關鍵字獲取對象並且使用類對象中的成員變量和方法,第一時間我們會想到可以使用反射去實現這些功能,反射很強大,學會了我們可以搭配很多東西一起使用,下面我們一起來學習使用反射吧!
我們使用一個Book類來實現一下反射
代碼如下:
public class Book { private Integer id; private String name; public Integer age; public Book() { System.out.println("Public 無參構造函數"); } public Book(String name) { System.out.println("Public 帶參構造函數"); } private Book(String name,Double price){ System.out.println("Private 帶兩參構造函數"); } public void printAll(){ System.out.println("公開方法"); } private void printOne(){ System.out.println("私有方法"); } }
獲取類的三種方式
第一種:使用Class.forName(String classPath) //ClassPath:寫需要反射的類名,一般是以包名.類名
注意事項:這里會產生一個ClassNotFoundException異常,我們需要將異常處理或者拋出
返回值:Class對象
try {
Class clz = Class.forName("com.entity.Book");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
第二種:直接使用Class clz = 類名.class
這種情況一般在我們知道有這個類的時候去使用
Class clz = Book.class;
第三種:Class clz = 對象. getClass();
前提是對象已經被實例化出來了
Book book = new Book(); Class clz = book.getClass();
總結:這三種方法都有各自的優點,一般我們使用第一種比較多,按照自己的實際需求去使用才是最好的
獲取構造函數
getDeclaredConstructors(); 獲取所有的構造函數
getDeclaredConstructor(參數類型); 獲取一個所有的構造函數
getConstructors(); 獲取所有公開的構造函數
getConstructor(參數類型); 獲取單個公開的構造函數
使用方法:
//獲取所有的構造函數 Constructor[] constructors = clz.getDeclaredConstructors(); //獲取單個所有的構造函數 try { Constructor constructor = clz.getDeclaredConstructor(String.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } //獲取所有的公開構造函數 Constructor[] constructors1 = clz.getConstructors(); //獲取單個公開構造函數 try { Constructor constructor = clz.getConstructor(String.class); } catch (NoSuchMethodException e) { e.printStackTrace(); }
獲取修飾符
getModifiers(); //獲取所有修飾符
返回類型:整數類型,如果有兩個修飾符,則返回兩個修飾符之和,例如public static void getAll(){ }
返回值會是public和static之和
整數定義:
0--默認不寫 1--public 2--private 4--protected
8--static 16--final 32--synchronized
64--volatile 128--transient 256--native
512--interface 1024--abstract
for (Constructor constructor : constructors) { System.out.println(constructor.getModifiers()); }
Modifier.isStatic(clz.getModifiers) //判斷是否是static類型
Modifier中還有一些判斷其它的方法,都是以is開頭
獲取名字
返回類型:String,可以反射類名,方法名,構造函數名等等
getName(); //獲取全名 例如:com.bean.Book
getSimpleName() //獲取類名 例如:Book
Class clz = Book.class; String name1 = clz.getName(); String name2 = clz.getSimpleName();
獲取包
返回類型:package
getPackage();
Package aPackage = clz.getPackage();
獲取接口
返回類型:Class[] interfaces
getInterfaces()
Class[] interfaces = clz.getInterfaces();
獲取父類/超類
返回類型:Class superclass
getSuperclass()
Class superclass = clz.getSuperclass();
獲取方法
getMethods() //獲取所有公開的方法
注意:它會將系統自帶的方法也得到
Class clz = Class.forName("Book");
Method[] methods = clz.getMethods(); //獲取所有的公開方法
for (Method method : methods) {
System.out.println(method.getName());
}

getMethod(String name) //獲取單個公開的方法,參數是可以指定方法名
Method method = clz.getMethod("printAll"); //獲取單個的公開方法
method.invoke(clz.newInstance(),null);

getDeclaredMethods() //獲取所有的方法
注意:它不會獲取系統自帶的方法
Method[] methods1 = clz.getDeclaredMethods(); //獲取所有方法 for (Method method1 : methods1) { System.out.println(method1.getName()); }

getDeclaredMethod(String name) //獲取單個的所有方法 參數是可指定方法名
Method method1 = clz.getDeclaredMethod("printOne"); //獲取單個所有的方法
System.out.println(method1.getName());

獲取字段
公開(Public)
getFields() //獲取所有的公開字段
getField(String name) //參數可以指定字段 獲取單個public字段
所有
getDeclaredFields() //獲取所有的字段
getDeclaredField(String name) //獲取單個字段 參數可以指定字段
Class clz = Book.class; //Public Field[] fields = clz.getFields(); //所有公開字段 Field id = clz.getField("age"); //age字段 //所有 Field[] declaredFields = clz.getDeclaredFields(); //所有字段 clz.getDeclaredField("name"); //name字段
實例化對象
newInstance(Object initargs)
第一種方式
Class clz = Book.class; Object obj = clz.newInstance(); //將創建一個無參book對象
第二種方式
Class clz = Book.class; Constructor constructor = clz.getDeclaredConstructor(); //獲得無參構造 Object obj = constructor.newInstance(); //實例化book對象
設置訪問屬性
clz.setAccessible(true) //可訪問
clz.setAccessible(false) //不可訪問
//默認是false
Field id = clz.getField("age"); //age字段 id.setAccessible(true); //設為可訪問 id.setAccessible(false); //設為不可訪問
使用方法
method.invoke(Object obj,Object... args)
obj:如果是實例方法,則放個該方法的類對象給它
obj:靜態方法,寫null
args:方法的參數值,沒有寫null,或不寫都行
Method method = clz.getMethod("printAll"); //獲取單個的公開方法
method.invoke(clz.newInstance(),null); //使用方法
當然,這些都只是常用的,反射不僅僅是只有這些
