反射 一.獲得Class文件對象的三種方式(返回值都是Class類的對象) 1.通過類名調用class()獲得。 格式:類名.class(); 2.通過對象調用getClass()方法獲得; 格式:對象名.getClass(); 3.通過Class類的靜態方法forName()獲得 格式:Class ...
反射
一.獲得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 }