Java反射

1、什么是反射?        

        反射是运行之间把类中的成员抽取为其它类的过程。

 2、为什使用反射?

        反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法或属性。

3、反射的应用场景?

        idea通过反射获取类中所有的method方法对象以提示框的形式列出

        jdbc对数据库的操作          

        mybatis中

        spring容器根据传入的类路径创建对象

        工厂模式中的简单工厂模式优化

         代理模式中的动态代理方式实现

 4、获取Class反射类的三种方式         

        //通过类直接获取反射类
        Class<People> peopleClass = People.class;
        //通过类路径获取反射类
        Class<?> aClass = Class.forName("com.tian.entity.People");
        //通过对象获取反射类
        People people = new People();
        Class<? extends People> aClass1 = people.getClass();

5、Class.newInstance()和Constructor.newInstance() 的区别

         class.newInstance()方法自9被弃用了

    @CallerSensitive
    @Deprecated(since="9")
    public T newInstance()
        throws InstantiationException, IllegalAccessException
    {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
        }

        // Constructor lookup
        Constructor<T> tmpConstructor = cachedConstructor;
        if (tmpConstructor == null) {
            if (this == Class.class) {
                throw new IllegalAccessException(
                    "Can not call newInstance() on the Class for java.lang.Class"
                );
            }
            try {
                Class<?>[] empty = {};
                final Constructor<T> c = getReflectionFactory().copyConstructor(
                    getConstructor0(empty, Member.DECLARED));
                // Disable accessibility checks on the constructor
                // access check is done with the true caller
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction<>() {
                        public Void run() {
                                c.setAccessible(true);
                                return null;
                            }
                        });
                cachedConstructor = tmpConstructor = c;
            } catch (NoSuchMethodException e) {
                throw (InstantiationException)
                    new InstantiationException(getName()).initCause(e);
            }
        }

        try {
            Class<?> caller = Reflection.getCallerClass();
            return getReflectionFactory().newInstance(tmpConstructor, null, caller);
        } catch (InvocationTargetException e) {
            Unsafe.getUnsafe().throwException(e.getTargetException());
            // Not reached
            return null;
        }
    }

 通过该方法只能创建无参的对象实例

        Constructor.newInstance()方法是JDK9以及更高版本使用的,该方法根据构造函数创建对象实例,可以根据任意的构造函数创建对象。

        Class.newInstance()和Constructor.newInstance()的用法:
        //jdk 8版本以后过时了
        People people1 = peopleClass.newInstance();
        System.out.println(people1);
        //通过无参构造器创建对象实例
        Constructor<People> constructor = peopleClass.getConstructor();
        People people2 = constructor.newInstance();
        System.out.println(people2);
        //有参构造器创建对象实例
        Constructor<People> constructor1 = peopleClass.getConstructor(String.class,         
        LocalDate.class);
        People people3 = constructor1.newInstance("Run",LocalDate.now());
        System.out.println(people3);

6、如何通过反射获取类上面的注解

        //获取该类上的所有注解对象
        Annotation[] annotations = peopleClass.getAnnotations();
        System.out.println(annotations);

        //通过注解类型获取注解类对象
        MyAnnotation annotation = peopleClass.getAnnotation(MyAnnotation.class);
        System.out.println(annotation.value());

 7、如何通过反射获取 Method方法类对象

        //获取该类中所有方法的对象
        Method[] declaredMethods = peopleClass.getDeclaredMethods();
        for (Method m:declaredMethods) {
            System.out.println(m);
        }

        //通过方法名和参数类型获取该类指定的方法对象
        Method getName = peopleClass.getDeclaredMethod("getName");
        System.out.println("==============getName=================");
        System.out.println(getName);


        //获取自己和长辈中所有的public的方法对象
        Method[] methods = peopleClass.getMethods();
        System.out.println("============getMethods====================");
        for (Method m:methods) {
            System.out.println(m);
        }

        //通过方法名和参数获取自己和长辈中指定的public的方法对象 
        //注意:【People类没有重写equals方法】
        Method equals = peopleClass.getMethod("equals",Object.class);
        System.out.println("=================equals======================");
        System.out.println(equals);

8、Method类对象中常用的方法

        //?代表通配符
        Class<?> aClass = Class.forName("com.tian.entity.People");
        Constructor<?> constructor = aClass.getConstructor();
        Object o = constructor.newInstance();
        //通过getMethod()方法获取到setName方法对象,再通过invoke()方法执行setName方法为属性赋值
        //Object invoke(Object obj, Object... args) 其中invoke(创建的实例对象,参数)  ...代表 
        //着可变参数      
        aClass.getMethod("setName", String.class).invoke(o, "tian");
        //通过getMethod()方法获取到getName方法对象,再通过invoke()方法执行getName方法获取属性的值
        System.out.println(aClass.getMethod("getName").invoke(o));
        System.out.println(aClass.getDeclaredMethod("getName").invoke(o));
        //注意:【show方法是无参无返回值私有方法】
        Method show = aClass.getDeclaredMethod("show");
        //设置可以访问私有方法
        show.setAccessible(true);
        show.invoke(o);

9、如何通过反射获取Field属性对象的方式

        //获取该类的所有属性对象
        Field[] declaredFields = peopleClass.getDeclaredFields();
        //获取本类指定的属性对象
        Field name = peopleClass.getDeclaredField("name");
        //获取该类和长辈中所有public修饰的属性对象
        Field[] fields = peopleClass.getFields();
        //获取该类和长辈中指定的public修饰的属性对象
        Field name1 = peopleClass.getField("name");

10、Field类中常用的方法

        for (Field f:declaredFields) {
            //String getName() 获取属性名
            System.out.println(f.getName());
            //<T extends Annotation> T getAnnotation(Class<T> annotationClass) 获取对象中的                            
            //注解对象   
            MyAnnotation annotation = f.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.value());

        }
        
        name.setAccessible(true);
        //void set(Object obj, Object value) 为属性赋值  obj是创建的实例对象 value要赋的值
        name.set(people,"tian");
        System.out.println(name.get(people));

  • 20
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值