zoukankan      html  css  js  c++  java
  • java学习笔记之反射

    反射

    一.获得Class文件对象的三种方式(返回值都是Class类的对象)

      1.通过类名调用class()获得。

        格式:类名.class();

      2.通过对象调用getClass()方法获得;

        格式:对象名.getClass();

      3.通过Class类的静态方法forName()获得

        格式:Class.forName(String  全类名);

     1 //演示
     2 //定义一个Person类,同一个java文件中,可以有多个类,但只有一个public修饰的类
     3 class Person  {}
     4 public class Demo{
     5    public static void main(String[]  args){
     6        //使用类名获得
     7          Class clazz1= Person.class();
     8        //使用对象获得
     9          Class  clazz2=new Person().getClass();
    10        //使用Class类的静态方法获得
    11          Class  clazz3=Class.forName("xxxxxx.Person");     
    12    }
    13 
    14 }
    15     

    二.使用反射技术获得构造方法

    //定义一个Person类,
    public class Person{
       private  String name ;
       private  int  age;
       set/get方法
       public Person(){}
       public Perosn(String name){
          this.name=name;
       }
    }

      1.使用反射获得public 修饰的无参构造;

         格式: Constructor   con= clazz.getConstructor();

    1 public static void func(){
    2     //先获得Class文件对象
    3     Class  clazz= Class.forName("xxxx.Person");
    4     //获得无参构造方法
    5     Constructor  con=clazz.getConstructor();
    6     //获得这个类的实例
    7     Object  obj=con.newInstance();
    8 }      

      2.使用反射获取public修饰的有参数构造

        格式: Constructor   con= clazz.getConstructor(参数的Class类型的文件对象);

    1 public static void func(){
    2      //先获得Class文件对象
    3      Class  clazz= Class.forName("xxxx.Person");
    4      //获得带参数构造方法
    5      Constructor  con=clazz.getConstructor(String.class);
    6      //获得这个类的实例
    7      Object  obj=con.newInstance("张三");
    8  }      

      3.简化版获得public修饰的无参构造的实例方法

    public static void func (){
       Class  clazz = Class.forName("xxxxx.Person");
       Object obj = clazz.newInstance();
    }

      4.暴力反射获取private 修饰的构造方法:

    public static void func(){
       //获得Class文件对象
       Class  clazz= Class.forName("xxxxx.Person");
        //获得私有的无参数构造方法
       Constructor   con =clazz.getDeclaredConstructor();
       // 暴力访问权限
       con.setAccessible(true);
        //获得实例对象
       Object  obj = con.newInstance();
    }
    
    
        

    三.使用反射技术获得成员方法

      1.获得public 修饰的无参方法

             步骤: 首先获得Class文件对象。然后通过文件对象调用getMethod(“方法名”,参数的Class类型文件对象*无参的不需要写)方法,获得Method对象 ,最后使用Method对象的  invoke(类对象,参数值*无参的不需要写)方法调用,有返回值的方法,会返回Object类型的;

    1 public static  void  func(){
    2    //获得Class文件对象
    3    Class  clazz= Class.forName("xxxx.Person");
    4    //获得Method方法对象
    5     Method  method =clazz.getMethod("getName");
    6     //调用方法
    7     Object  obj = method.invoke(clazz.newInstance);
    8 }      

      2.获得public修饰的有参数的方法

    1 public static void func(){
    2     //获得Class文件对象
    3    Class  clazz  =Class.forName("xxxxx.Perosn");
    4     //通过文件对象获得Method对象
    5    Method  m= clazz.getMethod("setName", String.class);
    6     //执行调用方法
    7    m.invoke(clazz.newInstance(),"张三");
    8 }        

      3.通过暴力反射获取私有的方法

     1 public  static void  func(){
     2     //获取Class文件对象
     3     Class  clazz = Class.forName("xxxx.Perosn");
     4     //通过Class文件对象的getDeclaredMethod()方法获取私有的方法对象
     5     Method m =clazz.getDeclaredMethod("私有方法名");
     6     //设置访问权限
     7     m.setAccessible(true);
     8     //调用方法
     9     m.invoke(clazz.newInstance());
    10 }       

    四.使用反射技术获取成员变量 

      1.操作public修饰的成员变量的值

        步骤:首先获取Class文件对象,然后通过Class文件对象调用getField(“成员变量名”)方法获得Field字段对象,然后再通过set(成员变量所在类的实例,“所要赋的值”)方法进行成员变量的赋值,或者通过方法get(成员变量所在类的实例)获取值;

     1 public static  void  func(){
     2     //通过Class  的静态方法forName();获得Class文件对象
     3    Class  clazz = Class.forName("xxxxx.Person");
     4     //通过newInstance();方法获取实例
     5    Object obj = clazz.newInstance();
     6     //通过getField(“成员变量的名字”)方法获取字段对象
     7     Field   f= clazz.getField("name");
     8     //操作成员变量   有两种  一个赋值,一个取值
     9     //赋值通过set(对象,要赋的值)
    10     f.set(obj,"张三");
    11     //取值通过get(对象);
    12     Object name = f.get(obj);
    13 
    14 }        

      2.通过暴力反射操作private修饰的成员变量

     1   public static  void  func(){
     2       //通过Class  的静态方法forName();获得Class文件对象
     3      Class  clazz = Class.forName("xxxxx.Person");
     4       //通过newInstance();方法获取实例
     5      Object obj = clazz.newInstance();
     6       //通过getDeclaredField(“成员变量的名字”)方法获取字段对象
     7       Field   f= clazz.getDeclaredField("name");
     8       //设置访问权限
     9       f.setAccessible(true);
    10       //操作成员变量   有两种  一个赋值,一个取值
    11       //赋值通过set(对象,要赋的值)
    12      f.set(obj,"张三");
    13      //取值通过get(对象);
    14      Object name = f.get(obj);
    15  
    16  }

     五.BeanUtils包的使用

       1.Java Bean类的组成(三样一样也不可以缺少)

         无参构造

         set/get方法

                      成员变量

       2.BeanUtils 工具类的setProperty()方法

     1 /*
     2  * BeanUtils工具类:
     3  *         该方法可以给任何一个对象的任何一个变量赋任何值
     4  *         参1:表示对象
     5  *         参2;表示变量名字
     6  *         参3:表示给变量赋的值
     7  *         setProperty(Object obj,String name,Object value)
     8  */
     9 public class Demo01BeanUtils {
    10     public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
    11         //1:创建Student对象
    12         Student stu = new Student();
    13         //2:使用BeanUtils给工具类赋值
    14         //name --->setName --->反射setName
    15         //如果你传入的是字符串,则该方法可以自动的将字符串转为对象的类型
    16         BeanUtils.setProperty(stu, "name", "诗诗");
    17         BeanUtils.setProperty(stu, "age",  "33");
    18         
    19         //3:打印对象
    20         System.out.println(stu);
    21     }
    22 }

      3.BeanUtils 工具类的getProperty()方法

     1 /*
     2  * BeanUtils工具类:
     3  *      可以获取任意的任意变量的值
     4  *     参1:表示对象
     5  *     参2:变量的名字
     6  *    getProperty(Object obj,String name)
     7  */
     8 public class Demo02GetProperty {
     9     public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    10         //1:创建Student对象
    11         Student stu = new Student("冰冰",42);
    12         
    13         //2:通过getProperty获取对象的值
    14         //改方法返回的都是String类型
    15         //name --->getName --->反射getName--->
    16         String name = BeanUtils.getProperty(stu, "name");
    17         String age = BeanUtils.getProperty(stu, "age");
    18         //3:打印值
    19         System.out.println(name+":"+age);
    20     }
    21 }

      4.BeanUtils 工具类的populate()方法

     1 /*
     2  * BeanUtis的工具类:
     3  *         也可以给任何对象的任何变量赋任何值和setProperty
     4  *         如果一个类中有数组的成员变量,则可以使用该方法
     5  *         populate(Object bean, Map<String,String[]> properties) 
     6  *      参1:表示对象
     7  *      参2:表示Map集合
     8  *          键:变量的名字
     9  *          值:就是变量的值
    10  */
    11 
    12 public class Demo03Populate {
    13 
    14     public static void main(String[] args) throws IllegalAccessException, InvocationTargetException {
    15         //1:创建User对象    
    16         User user = new User();
    17         //2:通过populate给对象赋值 
    18         //2.1 创建Map集合对象
    19         HashMap<String, String[]> map = new HashMap<String, String[]>();
    20         //2.2 给集合添加数据
    21         //如果你的变量不是数组,该方法会将数组中下标为0的值赋值给变量
    22         //如果你的变量是数组,则全部赋值
    23         map.put("name", new String[]{"刘涛","柳岩"});
    24         map.put("age", new String[]{"18"});
    25         map.put("hobbies", new String[]{"美女","代码","台球"});
    26         
    27         BeanUtils.populate(user, map);
    28         //3:打印值
    29         
    30         System.out.println(user);
    31     }
    32 
    33 }

     六.泛型的擦除Demo

     1 //泛型的擦除
     2 public class TestDemo2 {
     3     public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
     4         ArrayList<Integer> list = new ArrayList<Integer>();
     5         
     6         list.add(123);
     7         list.add(456);
     8 //        list.add("hello");
     9         
    10         //利用所学的知识,在该集合中添加字符串
    11         Class<?> clazz = list.getClass();
    12         Method method = clazz.getMethod("add", Object.class);
    13         method.invoke(list, "hello"); //add
    14         method.invoke(list, true);   //add
    15         method.invoke(list, 12.34); //add
    16         
    17         System.out.println(list);
    18         
    19     }
    20 }
  • 相关阅读:
    Android 平板模拟器内存修改
    UI设计另类,创意的网站和App 集合(持续更新)
    Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性
    shape和selector的结合使用
    RGB浅谈
    Android开发大牛们的博客地址(持续更新)
    解决ViewPager添加点击监听器无触发的问题
    VC 输出闪烁的字母
    计算机体系结构精要
    Xmanager远程连接Ubuntu,窗口无法输入字母'd'
  • 原文地址:https://www.cnblogs.com/xuzhaocai/p/8120637.html
Copyright © 2011-2022 走看看