zoukankan      html  css  js  c++  java
  • 反射

    反射机制介绍

    JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。

    获取 Class 对象的四种方式

    1.知道具体类的情况下可以使用:

    Class alunbarClass = TargetObject.class;

    但是我们一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象,通过此方式获取Class对象不会进行初始化

    2.通过 Class.forName()传入类的路径获取:

    Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject");

    Class.forName(className)方法,内部实际调用的是一个native方法 forName0(className, true, ClassLoader.getClassLoader(caller), caller);

    第2个boolean参数表示类是否需要初始化,Class.forName(className)默认是需要初始化。

    一旦初始化,就会触发目标对象的 static块代码执行,static参数也会被再次初始化。

    3.通过对象实例instance.getClass()获取:

    Employee e = new Employee();
    Class alunbarClass2 = e.getClass();

    4.通过类加载器xxxClassLoader.loadClass()传入类路径获取

    class clazz = ClassLoader.LoadClass("cn.javaguide.TargetObject");

    通过类加载器获取Class对象不会进行初始化,意味着不进行包括初始化等一些列步骤,静态块和静态对象不会得到执行

    使用反射操作这个类的方法以及参数

    package cn.javaguide;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Main {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
            /**
             * 获取TargetObject类的Class对象并且创建TargetObject类实例
             */
            Class<?> tagetClass = Class.forName("cn.javaguide.TargetObject");
            TargetObject targetObject = (TargetObject) tagetClass.newInstance();
            /**
             * 获取所有类中所有定义的方法
             */
            Method[] methods = tagetClass.getDeclaredMethods();
            for (Method method : methods) {
                System.out.println(method.getName());
            }
            /**
             * 获取指定方法并调用
             */
            Method publicMethod = tagetClass.getDeclaredMethod("publicMethod",
                    String.class);
    
            publicMethod.invoke(targetObject, "JavaGuide");
            /**
             * 获取指定参数并对参数进行修改
             */
            Field field = tagetClass.getDeclaredField("value");
            //为了对类中的参数进行修改我们取消安全检查
            field.setAccessible(true);
            field.set(targetObject, "JavaGuide");
            /**
             * 调用 private 方法
             */
            Method privateMethod = tagetClass.getDeclaredMethod("privateMethod");
            //为了调用private方法我们取消安全检查
            privateMethod.setAccessible(true);
            privateMethod.invoke(targetObject);
        }
    }

    反射机制优缺点

    • 优点: 运行期类型的判断,动态加载类,提高代码灵活度。
    • 缺点: 1,性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的 java 代码要慢很多。2,安全问题,让我们可以动态操作改变类的属性同时也增加了类的安全隐患。
     
  • 相关阅读:
    [译]CasperJS,基于PhantomJS的工具包
    [译]JavaScript:typeof的用途
    [译]JavaScript写的一个quine程序
    [译]Ruby中的解构赋值
    [译]DOM:元素ID就是全局变量
    [译]ECMAScript 6中的集合类型,第一部分:Set
    [译]JavaScript:Array.prototype和[]的性能差异
    [译]Web Inspector开始支持CSS区域
    [译]JavaScript:反科里化"this"
    [译]JavaScript:用什么来缩进
  • 原文地址:https://www.cnblogs.com/ningkuan/p/14438760.html
Copyright © 2011-2022 走看看