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 }
posted @ 2017-12-26 23:49  猿上生活  阅读(288)  评论(0编辑  收藏  举报