說明:pathName:指一個類的全名稱【全限定類名:包路徑+類名】java
//定義一個Person類 package com.ujiuye.demo; public class Person { String name;
int age; public Person(String name) { super(); this.name = name; }
public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public Person(int age) { super(); this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } } //定義一個測試類 package com.ujiuye.demo; public class Demo_Class { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //使用反射技術 獲得Person類的字節碼文件的對象 //第一種方式 對象法 Person p = new Person(); //clazz1 是class類的對象 [它person.class這個文件在內存中的對象形式] //class類是全部字節碼文件內存對象對應的類型 [一個class的對象對應一個.class爲後綴名的文件] //class的對象是內存中的字節碼文件資源的體現,.class文件是磁盤中字節碼資源的體現 //參考 file類 file類是全部磁盤文件在內存在的對象對應的類型 Class clazz1 = p.getClass(); //對象名.getClass()獲得內存中字節碼文件對象 //第二種方式 類名錶示.class 文件 ;類名.class 就是字節碼文件對象 Class clazz2 = Person.class; //第三種方式 使用全限定類名 [類字節碼文件所在的包路徑] 獲得字節碼文件對象 Class<?>clazz3 = Class.forName("com.ujiuye.demo.Person"); } }
屬於Class類的方法:編程
代碼示例app
package com.ujiuye.demo; public class Demo_Class { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //使用反射技術 獲得Person類的字節碼文件的對象 //對象法 Person p = new Person(); //clazz1 是class類的對象 [它person.class這個文件在內存中的對象形式] //class類是全部字節碼文件內存對象對應的類型 [一個class的對象對應一個.class爲後綴名的文件] //class的對象是內存中的字節碼文件資源的體現,.class文件是磁盤中字節碼資源的體現 //參考 file類 file類是全部磁盤文件在內存在的對象對應的類型 Class clazz1=p.getClass(); //對象名.getClass()獲得內存中字節碼文件對象 //第二種方式 類名錶示.class 文件 ;類名.class 就是字節碼文件對象 Class clazz2 =Person.class; //第三種方式 使用全限定類名 [類字節碼文件所在的包路徑] 獲得字節碼文件對象 Class<?>clazz3 =Class.forName("com.ujiuye.demo.Person"); //經過字節碼文件對象獲得對應類的對象 Person person= (Person)clazz3.newInstance(); System.out.println(person); } }
注意事項:反射在實例化對象的時候默認走的是空參構造,使用反射技術的時候保證操做的類必須提供空參構造框架
代碼示例1:【使用new對象的方式】jvm
//定義一個方法
package com.ujiuye.demo; public class FruitMachine { // 榨果汁 public void getJuice(Fruit f) { f.flowJuice(); } }
//定義一個水果接口 package com.ujiuye.demo; public interface Fruit { // 出果汁 void flowJuice(); }
//定義一個蘋果類實現接口 package com.ujiuye.demo; public class Apple implements Fruit{ @Override public void flowJuice() { System.out.println("蘋果汁"); } }
//定義一個橘子類實現接口
package com.ujiuye.demo; public class Orange implements Fruit{ @Override public void flowJuice() { System.out.println("橘子汁"); } }
//定義測試類 package com.ujiuye.demo; public class Test { public static void main(String[] args) { FruitMachine machine = new FruitMachine(); // 想喝蘋果汁 // Apple apple = new Apple(); // machine.getJuice(apple); Orange orange = new Orange(); machine.getJuice(orange); } }
代碼示例2:【使用反射方式】ide
package com.ujiuye.demo;
import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; public class Test { public static void main(String[] args) throws Exception { FruitMachine machine = new FruitMachine(); // 想喝蘋果汁 // Apple apple = new Apple(); // machine.getJuice(apple); /*Orange orange = new Orange(); machine.getJuice(orange);*/ // 使用反射技術 // 首先使用熟悉的io流技術把文件中的內容讀到 使用字符緩衝流一次讀一行讀到內容 BufferedReader br = new BufferedReader(new FileReader("a.properties"));
//a.properties文件裏面的內容是 com.ujiuye.demo.Apple;com.ujiuye.demo.Orange
String name = br.readLine();// 是一個類的全限定類名
// 使用反射技術獲得對應類的實例化對象
Class<?> clazz = Class.forName(name);
Fruit f =(Fruit) clazz.newInstance();
machine.getJuice(f);
br.close(); //關流
}
}
代碼示例測試
package com.ujiuye.demo;
import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; public class Demo_Constractor { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //操做person類 先獲得person的字節碼文件對象 //有三種方式 Class<?> clazz = Class.forName("com.ujiuye.demo.Person"); //獲得一個構造方法的對象 獲得 滿參構造 Constructor<?> c1 = clazz.getConstructor(String.class,int.class); Constructor<?> c2 = clazz.getConstructor(); System.out.println(c1); //public com.ujiuye.demo.Person(java.lang.String,int) //c1就是滿參構造方法在內存中的一個對象形式 //想要獲取類中全部的公共的構造方法對象 //person類裏面4個構造方法的對象都羅列出來了 Constructor<?>[] contructors = clazz.getConstructors(); System.out.println(Arrays.toString(contructors)); //輸出結果 //滿參 public com.ujiuye.demo.Person(java.lang.String,int) //age public com.ujiuye.demo.Person(int) //name public com.ujiuye.demo.Person(java.lang.String) //空參 public com.ujiuye.demo.Person() //構造方法的做用是什麼? 建立對象 給屬性賦值 Person p1 = (Person)c1.newInstance("baobao",30); System.out.println(p1); //Person [name=baobao, age=30] Person p2 =(Person)c2.newInstance(); //由於c2是空參全部輸出來是null值 System.out.println(p2); //Person [name=null, age=0] } }
代碼示例ui
package com.ujiuye.demo;
import java.lang.reflect.Field; import java.util.Arrays; public class Demo_Filed { public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException { //獲得對應的類的反射對象 [Preson] Class clazz= Person.class; //獲取對應的屬性對象, 只能獲取到public修飾的屬性對象 Field f1 = clazz.getField("name"); Field f2 = clazz.getField("age"); System.out.println(f1); //public java.lang.String com.ujiuye.demo.Person.name System.out.println(f2); //public int com.ujiuye.demo.Person.age //獲取全部公共的屬性 Field[] fields = clazz.getFields(); System.out.println(Arrays.toString(fields)); //輸出:[public java.lang.String com.ujiuye.demo.Person.name, public int com.ujiuye.demo.Person.age] //屬性的操做,獲取值 設置值 Person person =(Person) clazz.newInstance(); String name =(String )f1.get(person); //name屬性的對象對應的name屬性屬於哪一個類對象 [Person類對象] System.out.println(name); //空參,沒有賦值 null f1.set(person, "花花"); String name1 = (String)f1.get(person); System.out.println(name1); //花花 } }
代碼示例this
package com.ujiuye.demo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Arrays; public class Demo_Method { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { // 獲取person類中全部的方法,先獲得person類字節碼文件對象 // 三種獲取方式 Class clazz = Person.class; Class<? extends Person> clazz2 = new Person().getClass(); Class<?> clazz3 = Class.forName("com.ujiuye.demo.Person"); // 獲取想要操做方法的對象 // getname是空參全部後面的參數能夠不用 Method m1 = clazz.getMethod("getName"); // setName有參數,後面跟上參數類型.class Method m2 = clazz.getMethod("setName", String.class); System.out.println(m1); // public java.lang.String com.ujiuye.demo.Person.getName() System.out.println(m2); // public void com.ujiuye.demo.Person.setName(java.lang.String) Method[] methods = clazz.getMethods(); // 遍歷全部的方法 for (Method method : methods) { System.out.println(method); } System.out.println(Arrays.toString(methods)); // 輸出的是全部的方法包括object父類的方法 //方法用來幹嗎?調用的 方法的對象獲得了,想要方法對象對應的方法執行 Person person = (Person) clazz.newInstance(); String name = (String) m1.invoke(person); System.out.println(name); // 獲得的值是null值 //要執行哪一個方法就用哪一個方法對象去invoke m2.invoke(person, "花花"); //獲取值m1 get方法 String name1=(String)m1.invoke(person); System.out.println(name1); //花花 } }
getDeclaredXxx方法:能夠獲取類中的全部聲明的成員(屬性、方法、內部類),私有的成員也能夠獲取到。
Xxx表明 Field Constractor Methodspa
代碼示例
package com.ujiuye.demo;
import java.lang.reflect.Field; import java.lang.reflect.Method; public class Demo_Declared { public static void main(String[] args) throws NoSuchFieldException, SecurityException, NoSuchMethodException { //獲得反射對象 Class clazz = Person.class; /*Field name= clazz.getField("name"); Field age = clazz.getField("age"); System.out.println(name); //報錯 System.out.println(age); //報錯 */ //暴力反射方法,訪問屬性 //person類裏面的屬性默認的或私有的均可以獲取到 Field name = clazz.getDeclaredField("name"); Field age = clazz.getDeclaredField("age"); //增長這一步,把權限修飾符給改了,100%保證暴力的訪問到 name.setAccessible(true); System.out.println(name); //private java.lang.String com.ujiuye.demo.Person.name System.out.println(age); //private int com.ujiuye.demo.Person.age System.out.println(name.isAccessible()); //true //暴力反射方法,訪問構造方法 Method getName = clazz.getDeclaredMethod("getName"); System.out.println(getName); //private java.lang.String com.ujiuye.demo.Person.getName() } }
代碼示例
package com.ujiuye.demo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; public class Test_02 { public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { ArrayList<Integer>list = new ArrayList<>(); list.add(666); //list.add("abc"); //編譯階段泛型約束着添加的元素的數據類型 //獲取list集合字節碼文件對象 Class<? extends ArrayList> clazz = list.getClass(); //經過反射對象獲取 add方法的對象 Method add = clazz.getDeclaredMethod("add", Object.class); //執行add方法添加"abc"字符串 add.invoke(list, "abc"); System.out.println(list); //[666, abc] } }