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