反射,java反射
1.為什麼要使用反射?
需要在運行時才得知並使用編譯時間完全未知的類,建立其對象,改變其屬性,調用其方法。
2.什麼是反射?
允許程式在運行時,藉助Reflection API取得任何類的內部資訊,並直接操縱其屬性和方法。
3.類載入的過程?
當程式主動使用某個類時,該類還未被載入到記憶體,系統會通過以下三個步驟來載入類。
①類的載入:將.class檔案讀入到記憶體,並為之建立一個Class對象。由類載入器完成。
②類的串連:將類的二進位檔案合并到JRE中。
③類的初始化:由JVM進行類的初始化。
4.類載入器分類
①系統類別載入器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
②擴充類載入器
ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
③引導類載入器:負責載入核心類庫,無法直接擷取
ClassLoader parent = ClassLoader.getSystemClassLoader().getParent().getParent();
5.類載入的時機
①源檔案程式只有在需要使用該程式碼時,才會被載入。
②類的代碼只有在初次使用時才會被載入。
<1>通常發生於建立第一個對象的時候
<2>訪問static域和static對象時也會被載入。
<3>建立對象引用不載入類。
<4>可以歸結為:訪問static成員時,類會被初始化,因為構造器也是隱式的靜態方法。因此更準確的講,類在任何static成員訪問時載入。
6.擷取Class對象的四種方式
①
Class clazz = Person.class;
②
Person person = new Person();Class<? extends Person> clazz = person.getClass();
③
Class<?> clazz = Class.forName("com.nucsoft.refletciton.Person");
④
String className = "com.nucsoft.jdbc.Person";ClassLoader classLoader = Person.class.getClassLoader();Class<?> clazz = classLoader.loadClass(className);
7.通過反射建立執行個體
①預設是通過無參構造器來建立的
String className = "com.nucsoft.jdbc.Person";Class<?> clazz = Class.forName(className);Object newInstance = clazz.newInstance();
②也可以通過有參構造器來建立
Class<?> personClass = Class.forName("com.nucsoft.refletciton.Person");Constructor<?> constructor = personClass.getConstructor(int.class, String.class);Object obj = constructor.newInstance(2, "wangwu");
8.通過反射擷取屬性,改變屬性
①getField()方法只能擷取public修飾的屬性
②getDeclaredField()方法能擷取任意修飾符修飾的屬性對象(Field對象)。但是在修改私人屬性的時候,需要更改存取權限。
Class<?> personClass = Class.forName("com.nucsoft.refletciton.Person");Field personName = personClass.getDeclaredField("personName");personName.setAccessible(true);personName.set(person, "zhangsan");
9.通過反射擷取方法,調用方法
①getMethod() 方法只能擷取public修飾的方法
②getDeclaredMethod() 方法可以任意修飾符修飾的方法對象(Method對象)。但是在調用非公有方法時,需要設定存取權限。且通過method.invoke(obj, args)來調用、
Method sayMethod = personClass.getDeclaredMethod("say");sayMethod.setAccessible(true);sayMethod.invoke(person);
10.擷取父類泛型
Class clazz = Person.class; Type type = clazz.getGenericSuperClass(); ParameterizedType types = (ParameterizedType)type; for(Type t : types) { System.out.println(t); }
11.靜態代理
public interface Factory { void produce(); }public class NikeFactory implements Factory{ @Override public void produce() { System.out.println("生產Nike衣服....."); }}public class NikeProxy implements Factory{ private NikeFactory nikeFactroy = null; public NikeProxy(NikeFactory nikeFactory) { this.nikeFactroy = nikeFactory; } @Override public void produce() { nikeFactroy.produce(); }}public static void main(String[] args) { NikeFactory nikeFactory = new NikeFactory(); NikeProxy nikeProxy = new NikeProxy(nikeFactory); nikeProxy.produce(); }靜態代理
12.動態代理
public interface Factory { void produce(); }public class NikeFactory implements Factory{ @Override public void produce() { System.out.println("生產Nike衣服....."); }}public class MyInvocationHandler implements InvocationHandler { Object obj = null; public Object getProxy(Object obj) { this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(obj, args); } }public class DynamicProxy { public static void main(String[] args) { NikeFactory nikeFactory = new NikeFactory(); MyInvocationHandler myInvocationHandler = new MyInvocationHandler(); Object obj = myInvocationHandler.getProxy(nikeFactory); Factory factory = (Factory) obj; factory.produce(); }}動態代理
13.AOP
public interface Human { void walk(); void fly(); }public class SuperMan implements Human { @Override public void walk() { System.out.println("走走走走啊走!"); } @Override public void fly() { System.out.println("I belive i can fly..."); }}public class MyInvocationHandler implements InvocationHandler { Object obj = null; public Object getProxy(Object obj) { this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { HumanUtil.before(); Object returnValue = method.invoke(obj, args); HumanUtil.after(); return returnValue; }}public class HumanUtil { public static void before() { System.out.println("HumanUtil's before..."); } public static void after() { System.out.println("HumanUtil's after..."); }}public class AopTest { public static void main(String[] args) { SuperMan superMan = new SuperMan(); MyInvocationHandler myInvocationHandler = new MyInvocationHandler(); Object proxy = myInvocationHandler.getProxy(superMan); Human human = (Human)proxy; human.walk(); System.out.println("--------------------"); human.fly(); }}AOP