反射
一.获得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 }