反射

什么是反射

            反射是一种机制,可以在程序运行中根据该类的字节码对象动态的创建该类对象。

                 程序运行时,Java虚拟机会帮每一个类都创建一个字节码对象,(就是我们创建一个对象可以不用 " new  类名()",这种方式创建,使用其他方式创建)

 

反射的前提

              如果我们想通过反射创建一个类的对象,我们就先要获得这对象的字节码对象。

 

 获取字节码对象的三种方式

            方式一:通过  "对象名.getClass"  获取该类的字节码(很少使用)

 //创建String类的对象
        String s  = new String();
         Class c = s.getClass();  //通过对象的getClass方法获取字节码对象

        

         方式二:通过 “类名.class”  获取该类的字节码对象(很少使用)  

  //通过 类名.class 获取该类的字节码对象
          Class c = String.class;

        

        方式三:通过  “Class.forName("要获取字节码对象类的全包名")”   获取该类的字节码对象(常用)

                      //  Sudent类的全包名
   Class c = Class.forName("com.baidu.Student");

  

   Class对象(字节码对象)常用方法介绍

static  Class  forName(String classPath)根据参数给的全包名,获取该类的字节码对象
String  getName()获取该字节码对象的全包名
String  getSimpleName()获取这个字节码对象的类名
T  newInstance()创建这个字节码类型的对象

    

    使用反射技术操作构造方法创建类的对象

              通过Class对象操作构造需要使用到的方法介绍

Constructor   getConstructor(Class....parameterType)根据对应的参数类型获取对应的构造方法对象,只可以获取public修饰的
Constructor  getDeclaredConstructor(Class....parameterType)根据对应的参数类型获取对应的构造方法对象,可以获取privat修饰的
Constructor[]  getConstructors()获取全部构造方法对象,只能获取public修饰的
Constructor[]  getDeclaredConstructors()获取全部构造方法对象,可以获取private修饰的

       

    Constructor是一个构造方法对象,通过这个类的一些方法我们可以创建对象

T   newInstance(Object ....initargs)

根据传入的参数创建对象
void setAccessible(boolean b)取消私有方法的权限检查,如果调用该方法里面的值一般设置为true(暴力反射)
   //使用Student类的全包名通过反射获取到  Student的字节码对象
       Class c =  Class.forName("com.baidu.Student");
       //获取Student的有参构造方法的对象     参数为Student类里面对应的参数类型的Class对象类型
        //               Student(String name, int score)  这个是我Student类里面的一个有参构造方法
        //我要获取着构造方法的对象 所以我着方法里面的第一个参数就要是着参数类型的class对象类型
        //       String  name 对应 String.Class      int  score 对应  int.class  如果要获得无参数构造方法就不要传class对象
      Constructor constructor =  c.getConstructor(String.class,int.class);

      //调用newInstancec创建该类对象, 里面的参数顺序为我们上面传入的class对象对应的类型
        //c.getConstructor(String.class,int.class)   第一个为String的Clss对象所以我们第一个就要传入String类型的参数
        Student student = (Student) constructor.newInstance("小明", 23);

   使用反射技术通过创建私有构造方法创建对象

 //使用Student类的全包名通过反射获取到  Student的字节码对象
        Class c =  Class.forName("com.baidu.Student");
        //       private Student(String name)  这个是我Student类里面的一个私有的有参构造方法
        //                     getDeclaredConstructor获取私有的有参数构造方法
        Constructor constructor =  c.getDeclaredConstructor(String.class);
           //设置不进行权限检查      如果不设置就不能通过私有的构造方法创建对象
            constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("小明");

 

     通过反射操作成员变量

                  每一个成员变量就是一个Field对象

                  Class对象获得成员变量对象方法介绍

Field   getField(String name)获取指定名字的成员变量对象,只能获取public修饰的
Field   getDeclaredField(String  name)获取指定名字的成员变量对象,可以获取private修饰的
Field[]   getFilelds()获取该字节码对象类型的所有public修饰的成员变量
Field[]  getDeclaredField()获取该字节码对象类型的所有成员变量,包括private修饰的

      

    Field对象常用方法介绍

void  set(Object  o,Object o1)设置这个参数对象的值,第一个参数是对象,第二个参数为具体的值
void   setAccessible(boolean b)取消私有方法的权限检查,如果调用该方法里面的值一般设置为true(暴力反射

        //使用Student类的全包名通过反射获取到  Student的字节码对象
        Class c =  Class.forName("com.baidu.Student");
        //通过Student字节码对象 调用newInsranee方法 创建该类的对象
        Student s = (Student)c.newInstance();
        // 通过字节码对象调用getFild方法获取 成员变量对象  参数为你想设置的参数名字
        Field field = c.getField("name");
        // 第一个参数为  你要问哪一个student对象设置name这个值
        //第二个参数为   你要为name设置一个什么值
        field.set(s,"老王");

     获取私有成员变量的方法和上面获取私有构造方法的差不多,就没有解释了

               

       通过反射技术操作成员方法

                 每一个方法都是一个Method对象

               class对象获取成员方法对象方法介绍

Method   getMethod(String methodName,Class...params)d获取指定的方法对象,第一个参数为要获得的方法对象的方法名,第二个参数为方法要获得的那个方法的参数列表类型的class对象,只可以获取public修饰的
Method   getDeclaredMethod(String  methodName, Class...params)和上面的方法一样但是可以获得私有的
Method[]  getMethods()  获取这个class对象的类型全部的方法对象,只能获取public修饰的
Method[]  getDeclaredMethods()获取这个class对象的类型全部的方法对象,可以获取private修饰的

           

      Method常用方法介绍

Object   invoke(Obejct o,Object....args)调用方法,第一个为调用该方法的类,也就是获得这个method对象的字节码对象类型的对象
void  setAccessible(boolean b)取消私有方法的权限检查,如果调用该方法里面的值一般设置为true(暴力反射

           

        

  //使用Student类的全包名通过反射获取到  Student的字节码对象
        Class c =  Class.forName("com.baidu.Student");
        //通过Student字节码对象 调用newInsranee方法 创建该类的对象
        Student s = (Student)c.newInstance();
  // public void setName(String name)  这个为Student的方法
 //获取这个成员方法的对象    第一个参数为方法名,你要获取哪一个方法的Method对象
        //                     第二个参数为setName的参数类型的class对象
        Method m =  c.getMethod("setName",String.class);
        // 第一个参数为 哪一个对象调用着方法  ,第二个参数为传入方法的值
        m.invoke(s,"老刘");

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值