反射

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

  要想解刨一个类,必须先要获取到该类的字节码文件对象。而解刨使用的就是Class类中的方法。所以先要获取每一个字节码文件对应的Class类型的对象。

  阅读API的Class类得知,Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过类加载器中的defineClass方法自动构造的。

package com.zy.demo1;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {

    public static void main(String[] args) throws Exception {


                // 做反射第一步,获取某个类的class对象
                
                //第一种方式获取class对象
//                User user = new User();
//                Class class1 = user.getClass();
                
                //第二种方式获取class对象
                Class class2=User.class;
                
                //第三种方式
                Class class3 = Class.forName("com.zy.demo1.User");
        
                //三选一
                //----------------
                
                //就先在的User而言,我们怎么得到一个User对象[只有有构造方法,才能创建对象]
                //目标:是创建一个User对象
                //反射是具有超能力的
                //1得到构造对象
                Constructor ct = class2.getDeclaredConstructor();
                
                //暴力访问(报错遇到private)
                //java.lang.IllegalAccessException: Class com.zy.demo1.
                //Test can not access a member of class com.zy.demo1.User with modifiers "private"
                ct.setAccessible(true);//强行访问类中指定的私有构造方法
                
                //2利用构造对象,调用api创建一个实例对象
                
                User uu = (User)ct.newInstance();
                
                
                //3调用User中的一个对象
                System.out.println(uu.name);//不加暴力访问公开的name也不能访问
                
                
                
                
                
                //-------------------------------------
                //目标2:获取私有属性
                //我想拿到User中私有属性
                Field df = class2.getDeclaredField("age");
                //开暴力访问
                df.setAccessible(true);
                //得到对象
                Object object = df.get(uu);//传入刚才得到的一个user对象
                //输出
                System.out.println(object);//20[已经获取到了private age的值]
        
                
                //目标3:获取私有方法
                Method mt = class3.getDeclaredMethod("show");
                //开启暴力访问
                mt.setAccessible(true);
                //调用方法
                mt.invoke(uu);
                
                
                
                //小结:一个类中,(属性,方法,构造方法)[公私]都可以任意得到并使用
                
                
                
            //--------------------------------------------------
            //得到构造对象
                Constructor ct2 = class2.getConstructor(int.class,String.class);
                //创建一个实例
                User newInstance = (User)ct2.newInstance(30,"小明");
                //输出
                System.out.println(newInstance.toString());
                
                Constructor[] constructors = class2.getConstructors();
                System.out.println("长度:"+constructors.length);//1 一个公开的
                
                Constructor[] declaredConstructors = class2.getDeclaredConstructors();
                System.out.println(declaredConstructors.length);//2 公开私有都包括
            //-----------------------------------
            //属性
                Field field = class2.getField("name");
                Object object2 = field.get(uu);
                System.out.println(object2);//花花
                //-------------------
                Field[] fields = class2.getFields();
                System.out.println(fields.length);//1 获取公开的
                //------------------------
                Field[] declaredFields = class2.getDeclaredFields();
                System.out.println(declaredFields.length);//2 公开私有都包括    
                //暴力访问
                declaredFields[0].setAccessible(true);
                declaredFields[1].setAccessible(true);
                System.out.println(declaredFields[0].get(uu));
                System.out.println(declaredFields[1].get(uu));
    
            //---------------------------------------
            //方法
                Method method = class2.getMethod("speak");
                method.invoke(uu);
                
                Method[] methods = class2.getMethods();
                System.out.println(methods.length);//10 公开的方法[Object9个+自己1个]
                
                Method[] declaredMethods = class2.getDeclaredMethods();
                System.out.println(declaredMethods.length);//3  自己的公私
    
    }

}

 

posted @ 2019-07-04 20:14  勤奋的园  阅读(170)  评论(0编辑  收藏  举报