反射的实现
1.獲取類的字節碼對象
//獲取類的字節碼對象 public class Demo1 {public static void main(String[] args) throws ClassNotFoundException {//方式1:類名.ClassClass<?> clazz1 = Student.class;//方式2:對象名.getClass()Student student = new Student();Class<?> clazz2 = student.getClass();//方式3:Class.forName("類的全路徑名")Class<?> clazz3 = Class.forName("com.itheima1.Student");System.out.println(clazz1);System.out.println(clazz1 == clazz2);System.out.println(clazz2 == clazz3);} }2.獲取Constructor【構造方法】對象
學生類
public class Student {private String name;private int age;//公共的無參構造方法public Student() {System.out.println("public...Student...無參構造方法");}//公共的有參構造方法public Student(String name, int age) {System.out.println("name的值為:" + name + "age的值為" + age);System.out.println("public...Student...有參構造方法");}//私有的有參構造方法private Student(String name) {this.name= name ;System.out.println("name的值為:" + name);System.out.println("private...Student...有參構造方法");}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';} }獲取Constructor對象的方法
//獲取Constructor對象 public class Demo1 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {//首先得到Class對象再調用方法Class<?> clazz = Class.forName("com.itheima2.Student");//Constructor<T> getConstructor (class<?>... parameterTypes):返回單個公共構造方法對象【只能返回公共的,默認的等也不行】//Constructor<?> constructor = clazz.getConstructor();//constructor<T> getDeclaredConstructor (class<?>... parameterTypes):返回單個構造方法對象【可以返回私有的】Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);System.out.println(declaredConstructor);//Constructor<?>[] getConstructors ():返回所有公共構造方法對象的數組Constructor<?>[] constructors = clazz.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor);}//Constructor<?>[] getDeclaredConstructors ():返回所有構造方法對象的數組//Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();} }打印結果: ------------------------------------------------------------------------------------- public com.itheima2.Student(java.lang.String,int) public com.itheima2.Student(java.lang.String,int) public com.itheima2.Student()2.1 Constructor對象的使用
根據指定的構造方法創建對象:
Class.newInstance();只能反射無參的構造器,需要構造器可見;
Constructor.newInstance();可以反射任何構造器,可以反射私有構造器
3.獲取Field【成員變量】對象
學生類
public class Student {public String name;public int age;public String gender;private int money = 300; }獲取Field【成員變量】對象的方法
//獲取Field【成員變量】對象的方法 public class Demo1 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class<?> clazz = Class.forName("com.itheima4.Student");//Field[] getFields ():返回所有公共成員變量對象的數組//Field[] fields = clazz.getFields();//Field[] getDeclaredFields ():返回所有成員變量對象的數組Field[] declaredFields = clazz.getDeclaredFields();for (Field declaredField : declaredFields) {System.out.println(declaredField);}// Field getField (string name):返回單個公共成員變量對象// 想要獲取的成員變量必須是真實存在的//且必須是public修飾的Field f1 = clazz.getField("name");System.out.println(f1);// Field getDeclaredField (string name):返回單個成員變量對象Field f2 = clazz.getDeclaredField("money");System.out.println(f2);} }打印結果: ------------------------------------------------------------------------------------- public java.lang.String com.itheima4.Student.name public int com.itheima4.Student.age public java.lang.String com.itheima4.Student.gender private int com.itheima4.Student.money public java.lang.String com.itheima4.Student.name private int com.itheima4.Student.money3.1 Field對象的使用
根據指定的構造方法創建對象:
void set (object obj, object value):給obj對象的成員變量賦值為value【如果私有則需要暴力反射】
object get (object obj)返回由該 Field表示的字段在指定對象上的值
4 獲取Method【成員方法】對象
學生類
public class Student {//有一個參數的show方法public void show(String n) { System.out.println("show..." + n); }//有兩個參數的show方法private void show(String n, int m) {System.out.println("show..." + n +"..."+ m);}//有兩個參數,有返回值的方法public int sum(int n, int m) {return m + n;} }反射獲取學生類成員方法對象
<font color ="sky bule">反射獲取Method【成員方法】對象 public class Demo1 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {Class<?> clazz = Class.forName("com.itheima5.Student");//Method[] getMethods ():返回所有公共成員方法對象的數組,包括繼承的/*Method[] methods = clazz.getMethods();for (Method method : methods) {System.out.println(method);}*///Method[] getDeclaredMethods ():返回所有成員防法對象的數組,不包括繼承的Method[] declaredMethods = clazz.getDeclaredMethods();for (Method declaredMethod : declaredMethods) {System.out.println(declaredMethod);}//Method getMethod (string name,class<?>... parameterTypes) :返回單個公共成員方法對象//Method getDeclaredMethod (string name,Class<?>... parameterTypes):返回單個成員方法對象Method show = clazz.getDeclaredMethod("show", String.class, int.class);System.out.println(show);} }打印結果: ------------------------------------------------------------------------------------- public int com.itheima5.Student.sum(int,int) public void com.itheima5.Student.show(java.lang.String) private void com.itheima5.Student.show(java.lang.String,int) private void com.itheima5.Student.show(java.lang.String,int)4.1 Method對象的使用
method.invoke(student, 200, 100);
//反射獲取成員方法使用 public class Demo2 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//獲取類的字節碼文件Class<?> clazz = Class.forName("com.itheima5.Student");//創建一個學生對象【調用方法使用】Student student = (Student) clazz.getConstructor().newInstance();//獲取一個參數的show方法Method m1 = clazz.getMethod("show" , String.class);//System.out.println(m1);//執行m1.invoke(student,"hahah");//等價于obj.show (" hahah");//獲取兩個參數的show方法Method m2 = clazz.getDeclaredMethod("show", String.class, int.class);//System.out.println(m2);m2.setAccessible(true);//執行m2.invoke(student,"hehe",100);//等價于obj.show ("hehe",100);//獲取兩個int參數的sum方法[名稱參數必須一致,不能少]Method m3 = clazz.getMethod("sum",int.class,int.class);//System.out.println(m3);//執行int sum = (int) m3.invoke(student, 200, 100);System.out.println(sum);} }打印結果: ------------------------------------------------------------------------------------- show...hahah show...hehe...100 3005. 思路總結
<1>獲取Constructor對象
1.創建Class方法【Class.forName(“類的全路徑名”)】—通用
2.調用Class獲取Constructor對象方法
先看修飾符
如果需要訪問私有,則用帶Declared的方法
否則兩種類型的方法都可以使用
3.訪問單個構造:看參數類型和個數填寫方法參數得到Constructor對象
訪問多個構造:直接調用方法得到Constructor對象
4.得到Constructor對象后使用
Class.newInstance();只能反射無參的構造器,需要構造器非私有;
Constructor.newInstance();可以反射任何構造器,可以反射私有構造器【創建學生對象前加取消訪問檢查方法】
<2>Constructor.newInstance()得到的對象傳遞到 Field對象調用的set();get();參數中執行方法
<3>Constructor.newInstance()得到的對象傳遞到Method對象調用的invoke();參數中執行方法
總結
- 上一篇: icp备案怎么办理(小程序icp备案怎么
- 下一篇: 枚举的实现