121 项目 023 笔记向 反射
2019獨角獸企業重金招聘Python工程師標準>>>
反射
Class對象
Class 類是一切反射的根源
得到Class類的對象有一種方式:
通過Class實例化對象
- 調用無參構建
public T newInstance() throws InstantiationException.IllegalAccessException
此時類中必須聲明無參構造方法
- 調用有參構建
public Constructor<?>[] getConstructors() throws SecurityException
package com.laolang.se.fanshe;import com.laolang.se.fanshe.domain.User;import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException;public class Main {public static void main(String[] args) {Class<User> userClazz = User.class;// 調用無參構造User user = null;try {user = userClazz.newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}System.out.println(user);// 調用帶參構造// 獲取當前類的所有構造方法Constructor<?>[] constructors = userClazz.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor.getName());Class<?>[] parameterTypes = constructor.getParameterTypes();for (Class<?> parameterType : parameterTypes) {System.out.println(parameterType);}}// 獲取指定的構造方法try {Constructor<User> constructor = userClazz.getConstructor(Long.class,String.class,Integer.class);User laolang = constructor.newInstance(1L,"laolang",23);System.out.println(laolang);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}} }通過Class類取得類信息
- 取得類所在包
public Package getPackage() // 得到一個類所在包 public String getrName() // 得到名字
- 取得一個類中的全部方法
public Method[] getMethods() public int getModifiers() // Modifier.toString(moe); // 還愿修飾符 public Class<?> getReturnType() public Class<?>[] getParameterTypes() public Class<?>[] getExceptionTypes() public static String toString(int mod)
- 取得一個類中的全部屬性
public Field[] getFields() public Field[] getDeclaredFields() public Class<?> getType() public int getModifiers() public String getName()
package com.laolang.se.fanshe;import com.laolang.se.fanshe.domain.User;import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier;public class Main {public static void main(String[] args) {Class<User> userClazz = User.class;// 包名Package packages = userClazz.getPackage();System.out.println(packages.getName());// 得到類全名System.out.println(userClazz.getName());System.out.println("--- 得到所有的公有方法,包括父類的-----------------------------");// 得到方法// 所有的公有方法,包括父類的Method[] methods = userClazz.getMethods();for (Method method : methods) {System.out.println(method.getName());}System.out.println("--- 得到當前類所有聲明的方法-----------------------------------");// 得到所有聲明的方法,但不包括父類的methods = userClazz.getDeclaredMethods();for (Method method : methods) {System.out.println("方法名:" + method.getName() + " 修飾符:" + Modifier.toString(method.getModifiers()));}System.out.println("--- 得到所有屬性-----------------------------------");Field[] fields = userClazz.getDeclaredFields();for (Field field : fields) {System.out.println(field.getName());}} }通過Class類調用屬性或方法
- 調用類中的方法
調用類中的方法,傳入實例化對象,以及具體參數內容
public Object invoke(Object obj, Object... args)
- 直接調用屬性
1.取得屬性
public Object get(Object obj)
2.設置屬性
public void set(Object obj, Object value)
3.讓屬性對外可見
public void setAccessible(boolean flag)
package com.laolang.se.fanshe;import com.laolang.se.fanshe.domain.User;import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;public class Main {public static void main(String[] args) {Class<User> userClazz = User.class;try {User user = userClazz.newInstance();System.out.println(user);// 調用公有方法Method method = userClazz.getMethod("setName", String.class);method.invoke(user,"laolang");System.out.println(user);// 調用公有方法method = userClazz.getDeclaredMethod("say");// 跳過修飾符的檢查method.setAccessible(true);method.invoke(user);// 開啟修飾符的檢查method.setAccessible(false);//method.invoke(user);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}} }動態代理
所謂動態代理,即通過代理類:Proxy的代理,接口和實現類之間可以不直接發生聯系,而可以在運行期實現動態關聯
java動態代理主要是使用java.lang.reflect包中的兩個類
- InvocationHandler類
public Object invoke(Object obj, Method method, Object[] obs)
第一個參數obj指的是代理類,method是被代理的方法,obs是指被代理的方法的參數組。此方法由代理類來實現
- Proxy 類
動態代理其實是運行時生成class,所以我們必須提供一組interface,然后告訴他class已經實現了這些interface,而且在生成Proxy的時候,必須給他提供一個handler,讓他來接管的實際的工作
user
package com.laolang.se.fanshe.domain;import org.slf4j.Logger; import org.slf4j.LoggerFactory;/*** 被代理類*/ public class User implements Subject{private static final Logger log = LoggerFactory.getLogger(User.class);public User() {log.info("調用無參構造函數");}public User(Long id, String name, Integer age) {log.info("調用帶參構造函數");this.id = id;this.name = name;this.age = age;}private String say(){return name;}@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}private Long id;private String name;private Integer age;@Overridepublic void miai() {System.out.println("正在相親中...");} }subject
package com.laolang.se.fanshe.domain;/*** 要代理的主題接口*/ public interface Subject {/*** 相親*/public void miai(); }DynaProxy
package com.laolang.se.fanshe.domain;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;/*** 動態代理類*/ public class DynaProxy implements InvocationHandler {public DynaProxy(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object o = null;before();// 正在調用業務方法o = method.invoke(target,args);after();return o;}/*** 相親之前做的事*/private void before(){System.out.println("為代理人匹配對象");}/*** 相親之后做的事*/private void after(){System.out.println("本次相親結束");}/*** 被代理對象*/private Object target; }Main
package com.laolang.se.fanshe;import com.laolang.se.fanshe.domain.DynaProxy; import com.laolang.se.fanshe.domain.Subject; import com.laolang.se.fanshe.domain.User;import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy;public class Main {public static void main(String[] args) {User user = new User(1L,"老狼",23);DynaProxy dynaProxy = new DynaProxy(user);// 動態生成代理對象(類加載器,被代理接口,InvocationHandler)Subject subject = (Subject) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), dynaProxy);subject.miai();} }轉載于:https://my.oschina.net/iamhere/blog/858885
總結
以上是生活随笔為你收集整理的121 项目 023 笔记向 反射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决QT出现XXXX.dll不能加载问题
- 下一篇: Java NIO3:缓冲区Buffer