吉林手机版建站系统开发,如何建设企业网站呢,农业种植养殖网站建设,嘉兴网站制作报价反射的概念java 的放射机制#xff1a;在程序运行时#xff0c;程序有能力获取一个类的所有方法和属性#xff1b;并且对于任意一个对象#xff0c;可以调用它的任意方法或者获取其属性通俗解析#xff1a;java 文件需要编译成. class 文件才能被 jvm 加载使用, 对象的. c… 反射的概念java 的放射机制在程序运行时程序有能力获取一个类的所有方法和属性并且对于任意一个对象可以调用它的任意方法或者获取其属性通俗解析java 文件需要编译成. class 文件才能被 jvm 加载使用, 对象的. class 数据在 jvm 里就是 Class我们如果能拿到这个 Class对象就能获取该 Class对应的对象类型及在该类型声明的方法和属性值还可以根据 Class创建相应的类型对象通过 Field,Method 反过来操作对象java 相关类介绍类名描述Class代表类的实体在运行的 Java 应用程序中表示类或者接口Field类的成员变量(成员变量也称为类的属性)Method类的方法Constructor类的构造方法获取 Class 的三种方法1 通过已知的类型获取 class// 根据Example 获取Class 》Example.classpublic Class getExample(){ Class clazz Example.class;return clazz;}2 通过实例对象获取 classpublic Class getExampleByInstance(){ Example example new Example(); // getClass是Object类里面的方法《?》 是通配符 Class clazz example.getClass();return (Class)clazz;}3 通过 Class.forName 获取全路径指定类名的 class/\*\* forName0 本地方法C实现jvm调用 \* 1 className 是个类名 2 initialize 是否延迟加载 3 loader 加载器 \*/private static native Class forName0(String className, boolean initialize, ClassLoader loader, Class caller) throws ClassNotFoundException;public static Class forName(String className) throws ClassNotFoundException { Class caller Reflection.getCallerClass(); return forName0(className, true, ClassLoader.getClassLoader(caller), caller); }// 两个forName方法最终都会调用forName0方法去加载class public static Class forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException { .... return forName0(name, initialize, loader, caller); }// 示例:通过java.lang.Integer public Class getInteger()throws ClassNotFoundException{ Class clazz Class.forName(java.lang.Integer);return (Class)clazz;}JAVA 反射 APIClass 常用操作方法//获取所有的构造方法 / private publicpublic Constructor\[\] getDeclaredConstructors()//获取特定的构造方法 / private publicpublic Constructor getDeclaredConstructor(Class... parameterTypes) //获取类的父类public native Class getSuperclass() //获取类实现的接口private Class\[\] getInterfaces(boolean cloneArray) //获取在类内定义的内部类或接口public Class\[\] getDeclaredClasses()//获取所有的方法public Method\[\] getDeclaredMethods() throws SecurityException//根据方法名和参数获得特定的方法public Method getDeclaredMethod(String name, Class... parameterTypes) //获取类型的定义的所有属性public Field\[\] getFields() throws SecurityException// 根据属性命名获得特定的Fieldpublic Field getField(String name) Method 常用的操作方法//获得方法的放回类型public Class getReturnType() //获得方法的传入参数类型public Class\[\] getParameterTypes() //obj是实例对象args是方法反过来由Method控制对象的方法调用public Object invoke(Object obj, Object... args)Field 常用的操作方法//属性与obj相等则返回truepublic boolean equals(Object obj)//获得obj中对应的属性值public Object get(Object obj)//设置obj中对应属性值public void set(Object obj, Object value) Constructor//根据传递的参数创建类的对象:initargs 构造方法参数public T newInstance(Object... initargs) 1 根据 class 创建对象//方式一 clazz.newInstance()Class clazz Example.class;Example example clazz.newInstance();//方式二 先获取再由Constructorclazz.getConstructors()/getConstructor(...) //再由Constructor.newInstance 方法构造对象-----------------------------------------public class Example { private int value; public Example(){ } // 如果只声明有参构造函数clazz.newInstance()会报错 public Example(Integer value){ this.value value; } static public void main(String\[\] args) throws Exception{ Class clazz Example.class; //根据指定构造函数参数获取Constructor Constructor constructor clazz.getConstructor(Integer.class); Example example constructor.newInstance(100); System.out.println(example.value); }} 2 由 class 获取 Field并操作实例的属性public class Example { private int value , count; static public void main(String\[\] args) throws Exception{ Class clazz Example.class; //获取所有的属性getField只能获取public的属性 Field\[\] fs clazz.getDeclaredFields(); //根据名称获取指定 Field Field value clazz.getDeclaredField(value); Example example clazz.newInstance(); //使用反射机制可以打破封装性导致了java对象的属性不安全 value.setAccessible(true); //setAccessible(true)让private的参数可赋值操作 //由Field反过去设置example的值 value.set(example,100); System.out.println(example.value); }}3 由 class 获取 Method并反射调用实例方法public class Example { public static void main(String\[\] args) throws Exception { Class clazz Example.class; Example example clazz.newInstance(); Method\[\] methods clazz.getDeclaredMethods(); //getDeclaredMethod和getMethod是getMethod只能返回public的方法 Method method clazz.getDeclaredMethod(hello, String.class); method.setAccessible(true); method.invoke(example, cscw); } private void hello(String name) { System.out.println(name Hello!); }}cscw Hello!反射机制应用的场景1 动态拓展假设有同一组类是实现相同的接口并且类的加载方式不限制。当我们需要那种具体类实现的功能时只需加载. class 文件并获取对应的 Class对象。可以由 Class 或者 Constructor 实例化对象 instance根据接口定义可以获取 Class里的某一方法 Method并配合 instance 反射调用功能方法2 Spring 的 IOC 就是基于反射机制实现3 JDK 的动态代理反射和 JDK 动态代理在 Java 的 java.lang.reflect 包下提供了一个 Proxy 类和一个 InvocationHandler 接口。通过这个类和接口可以生成 JDK 动态代理类或动态代理对象public interface InvocationHandler { //所有方法都会调用此代理方法 Object invoke(Object var1, Method var2, Object\[\] var3) throws Throwable;} public class Proxy implements Serializable ... //根据interfaces和InvocationHandler生成代理对象 public static Object newProxyInstance(ClassLoader loader, Class\[\] interfaces, InvocationHandler h) ... JDK 的动态代理由 Proxy 和 InvocationHandler 实现而被代理对象必须实现一个接口。代理对象由 Proxy 生成可转为接口 interface 的实现类对象 OBJ。当调用 OBJ 的方法时则会触发 InvocationHandler.invoke参数依次为「代理对象」「Method 对象」, 和「方法 Method 所需的参数」。在 invoke 方法可以加入拓展的逻辑如日志记录操作「并可以在 invoke 里利用反射的技术调用被代理对象方法」示例public class ExampleFactory implements InvocationHandler{ private T target; //被代理对象 public T bind(T obj){ target obj;return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),this); } /\*\* Object o 是代理对象; o的方法调用 - ExampleFactory.invoke \* invoke(...) - 在invoke方法里面 反射调用代理对象方法增强逻辑 \*/ Override public Object invoke(Object o, Method method, Object\[\] objects) throws Throwable { //增强逻辑 System.out.println(log start); //反射调用被代理对象方法 Object result method.invoke(target,objects); System.out.println(log end);return result; }}-----------public interface Face { void hello(String name);}---------//被代理对象必须实现一个接口并由接口方法对方提供功能public class Example implements Face { public void hello(String name) { System.out.println(name Hello!); } public static void main(String\[\] args) { //ExampleFactory 相当于一个中介人 ExampleFactory factory new ExampleFactory(); //example 是代理对象 Face example exampleProxy.bind(new Example()); example.hello(思婷); }}-----log start思婷 Hello!log end欢迎指正文中错误