欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

121 项目 023 笔记向 反射

发布时间:2025/5/22 编程问答 68 豆豆
生活随笔 收集整理的这篇文章主要介绍了 121 项目 023 笔记向 反射 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

2019独角兽企业重金招聘Python工程师标准>>>

反射

Class对象

Class 类是一切反射的根源

得到Class类的对象有一种方式:

  • Object.getClass()
  • 类.class
  • Class.forName()
  • package com.laolang.se.fanshe;import com.laolang.se.fanshe.domain.User;public class Main {public static void main(String[] args) throws ClassNotFoundException {User laolang = new User(1001L,"laolang",23);User xiaodaima = new User(1001L,"laolang",23);Class laolangClazz = laolang.getClass();Class xiaodaimaClazz = xiaodaima.getClass();System.out.println(laolangClazz == xiaodaimaClazz );Class userClazz = User.class;System.out.println(userClazz == laolangClazz );Class userForName = Class.forName("com.laolang.se.fanshe.domain.User");System.out.println(userClazz == userForName );} }

    通过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 类
    protected Proxy(InvocationHandler h); static Class getProxyClass(ClassLoader loader, Class[] interfaces); static Object newProxyInstance(ClassLoader loader, Class[] interfaces , InvocationHandler h );

    动态代理其实是运行时生成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 笔记向 反射的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。