Java反射reflect學習 Class.forName()用法詳解
阿新 • • 發佈:2018-12-11
恰巧前段時間面試的時候問到了Java的反射,當時答得不是很好,正好抽空重新溫習下,本文只講解下通過反射獲取到類的屬性、構造方法、方法,關於類載入器(ClassLoader)將在其他文章中有具體介紹,本文不作介紹。
Class.forName()用法詳解
主要功能 Class.forName(xxx.xx.xx)返回的是一個類。 Class.forName(xxx.xx.xx)的作用是要求JVM查詢並載入指定的類,也就是說JVM會執行該類的靜態程式碼段。
A a = (A)Class.forName(“pacage.A”).newInstance();//這和你 A a = new A(); 是一樣的效果。
首先,通過Class獲取類的位元組碼
Class clazz = Class.forName("clazz.Test01");
1、獲取類的屬性
//獲取類的屬性物件,需要填寫屬性物件的名稱
Field f1=c.getField("name");//只能獲取public的物件
Field f2=c.getDeclaredField("age");//可以獲取到private的物件,這很吊吧
f2.setAccessible(true);//如果屬性是私有的,那麼就需要設定可訪問
2、利用Constructor建立物件
Constructor c = clazz.getConstructor(null);//獲取無參的建構函式
Constructor c = clazz.getConstructor(String.class);//獲取引數為String的建構函式Constructor c = clazz.getConstructor(String.class, int.class);//獲取引數為String,int的建構函式
Constructor c = clazz.getDeclaredConstructor(List.class);//獲取隱藏為private的建構函式
c.setAccessible(true);//暴力反射
建立物件的另外一種途徑,反射出類的無參建構函式並建立物件
Class clazz = Class.forName("com.marer.reflect.Person");
Person p = (Person) clazz.newInstance();
暴力反射獲取類的隱藏建構函式:Constructor.setAccessible(true);
3、利用Method 獲取類方法
Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的
methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法
Method m = clazz.getMethod("t2",String.class);//獲取指定方法t2
4、反射呼叫t2方法
Object o = clazz.newInstance();
m.invoke(o,"123");
package clazz; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class TestClazz { public static void main(String[] args) throws Exception{ try { Class<?> clazz = Class.forName("clazz.Test01"); //獲取本類的所有方法,存放入陣列 Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的 methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法 Method m = clazz.getMethod("t2",String.class); Object o = clazz.newInstance(); m.invoke(o,"123"); System.out.println("-------------------------"); for (Method method : methods) { System.out.println("方法名:"+method.getName()); //獲取本方法所有引數型別,存入陣列 Class<?>[] getTypeParameters = method.getParameterTypes(); if(getTypeParameters.length==0){ System.out.println("此方法無引數"); } for (Class<?> class1 : getTypeParameters) { String parameterName = class1.getName(); System.out.println("引數型別:"+parameterName); } System.out.println("****************************"); } Constructor<?>[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println("構造器名:"+constructor.getName()); } Constructor<?> c1 = clazz.getConstructor(null); System.out.println("構造器名:"+c1.getName()); Test01 o1 = (Test01)c1.newInstance(); System.out.println(o1); Constructor<?> c2 = clazz.getConstructor(String.class, String.class); System.out.println("構造器名:"+c2.getName()); Test01 o2 = (Test01)c2.newInstance("1", "1"); System.out.println(o2); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
主要功能 Class.forName(xxx.xx.xx)返回的是一個類。 Class.forName(xxx.xx.xx)的作用是要求JVM查詢並載入指定的類,也就是說JVM會執行該類的靜態程式碼段。
A a = (A)Class.forName(“pacage.A”).newInstance();//這和你 A a = new A(); 是一樣的效果。
首先,通過Class獲取類的位元組碼
Class clazz = Class.forName("clazz.Test01");
1、獲取類的屬性
//獲取類的屬性物件,需要填寫屬性物件的名稱
Field f1=c.getField("name");//只能獲取public的物件
Field f2=c.getDeclaredField("age");//可以獲取到private的物件,這很吊吧
f2.setAccessible(true);//如果屬性是私有的,那麼就需要設定可訪問
2、利用Constructor建立物件
Constructor c = clazz.getConstructor(null);//獲取無參的建構函式
Constructor c = clazz.getConstructor(String.class);//獲取引數為String的建構函式
Constructor c = clazz.getConstructor(String.class, int.class);//獲取引數為String,int的建構函式
Constructor c = clazz.getDeclaredConstructor(List.class);//獲取隱藏為private的建構函式
c.setAccessible(true);//暴力反射
建立物件的另外一種途徑,反射出類的無參建構函式並建立物件
Class clazz = Class.forName("com.marer.reflect.Person");
Person p = (Person) clazz.newInstance();
暴力反射獲取類的隱藏建構函式:Constructor.setAccessible(true);
3、利用Method 獲取類方法
Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的
methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法
Method m = clazz.getMethod("t2",String.class);//獲取指定方法t2
4、反射呼叫t2方法
Object o = clazz.newInstance();
m.invoke(o,"123");
package clazz; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class TestClazz { public static void main(String[] args) throws Exception{ try { Class<?> clazz = Class.forName("clazz.Test01"); //獲取本類的所有方法,存放入陣列 Method[] methods = clazz.getDeclaredMethods();////獲取自身所有的方法(private、public、protected,和訪問許可權無關),不包括繼承的 methods = clazz.getMethods();//獲取包括自身和繼承(實現)過來的所有的public方法 Method m = clazz.getMethod("t2",String.class); Object o = clazz.newInstance(); m.invoke(o,"123"); System.out.println("-------------------------"); for (Method method : methods) { System.out.println("方法名:"+method.getName()); //獲取本方法所有引數型別,存入陣列 Class<?>[] getTypeParameters = method.getParameterTypes(); if(getTypeParameters.length==0){ System.out.println("此方法無引數"); } for (Class<?> class1 : getTypeParameters) { String parameterName = class1.getName(); System.out.println("引數型別:"+parameterName); } System.out.println("****************************"); } Constructor<?>[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println("構造器名:"+constructor.getName()); } Constructor<?> c1 = clazz.getConstructor(null); System.out.println("構造器名:"+c1.getName()); Test01 o1 = (Test01)c1.newInstance(); System.out.println(o1); Constructor<?> c2 = clazz.getConstructor(String.class, String.class); System.out.println("構造器名:"+c2.getName()); Test01 o2 = (Test01)c2.newInstance("1", "1"); System.out.println(o2); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }