java反射机制原理详解_java反射机制的详细讲解
一 , 什么是java反射機制?
JAVA反射機制是在運行狀態中,對于任意一個實體類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。
1.意義
首先,反射機制極大的提高了程序的靈活性和擴展性,降低模塊的耦合性,提高自身的適應能力。
其次,通過反射機制可以讓程序創建和控制任何類的對象,無需提前硬編碼目標類。
再次,使用反射機制能夠在運行時構造一個類的對象、判斷一個類所具有的成員變量和方法、調用一個對象的方法。
最后,反射機制是構建框架技術的基礎所在,使用反射可以避免將代碼寫死在框架中。
正是反射有以上的特征,所以它能動態編譯和創建對象,極大的激發了編程語言的靈活性,強化了多態的特性,進一步提升了面向對象編程的抽象能力.
2.原理
反射機制(Reflection)是Java提供的一項較為高級的功能,它提供了一種動態功能,而此功能的體現在于通過反射機制相關的API就可以獲取任何Java類的包括屬性、方法、構造器、修飾符等信息。元素不必在JVM運行時進行確定,反射可以使得它們在運行時動態地進行創建或調用。反射技術在中間件領域應用得較多。
二 .實踐說明
通過反射Student類的屬性和方法
Student類的代碼:
package reflect;public class Student { //公有 的姓名 public String name="小明"; //公有 的年級 public String grade; //受保護的 年齡 protected int age; //私有的學分 private double credit=99.9; //默認的課程 String course; //無參構造方法 public Student(){ } //有參構造方法 public Student(String name) { this.name = name; } //公有的方法 public void getName(String name){ System.out.println("獲取姓名:方法調用了"+name); } //私有方法 private void getGrade(){ System.out.println("年級方法調用了"); } //受保護方法 protected int getCredit(int num){ System.out.println("獲取學分:"+num); return num; } @Override public String toString() { return "Student{" + "name='" + name + ''' + ", grade='" + grade + ''' + ", age=" + age + ", credit='" + credit + ''' + ", course='" + course + ''' + '}'; }}通過反射獲取類的對象
主方法的運行
import reflect.Student;public class Main { public static void main(String[] args) throws ClassNotFoundException { //1.獲取Class對象 //獲取類對象的第一種方式 Class stu = Class.forName("reflect.Student"); System.out.println("獲取類的對象1::"+stu); //獲取類對象的第二種方式 Class stu2 = Student.class; System.out.println("獲取類的對象2::"+stu); //獲取類對象的第三種方式 Class stu3 = new Student().getClass(); System.out.println("獲取類的對象3::"+stu); System.out.println(stu==stu2);//輸出true System.out.println(stu==stu3);//輸出true }}拋出異常:ClassNotFoundException 意思是沒有找到類的異常
運行結果:
解釋一下,在一個JVM中,一種類,只會有一個類對象存在。所以以上三種方式取出來的類對象,都是一樣的。
通過反射獲取Student屬性
import reflect.Student;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;public class Main { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //1.獲取Class對象 //獲取類對象的第一種方式 Class stu = Class.forName("reflect.Student"); System.out.println("獲取類的對象1::"+stu); //2.獲取字段 System.out.println("************獲取所有公有的字段********************"); Field[] fieldArray = stu.getFields(); //遍歷屬性 for(Field f : fieldArray){ System.out.println("獲取所有公有的字段"+f); } System.out.println("************獲取所有的字段(包括私有、受保護、默認的)********************"); fieldArray = stu.getDeclaredFields(); for(Field f : fieldArray){ System.out.println("獲取所有的字段(包括私有、受保護、默認的):"+f); } System.out.println("*************獲取公有字段**并調用***********************************"); Field field = stu.getField("name"); System.out.println("調用姓名"+field); //獲取一個對象 Object obj = stu.getConstructor().newInstance(); System.out.println("設置屬性之前:" + field.getName() + "===" + field.get(obj)); //為字段設置值 field.set(obj, "小明"); //驗證 Student stuObj = (Student)obj; System.out.println("設置屬性之后:" + field.getName() + "===" + field.get(obj)); System.out.println("**************獲取私有字段****并調用********************************"); Field credit = stu.getDeclaredField("credit"); System.out.println("獲取私有字段****并調用"+credit); credit.setAccessible(true);//暴力反射,解除私有限定 System.out.println("設置屬性之前:" + credit.getName()+"===" + credit.get(obj)); credit.set(obj, 999); System.out.println("設置屬性之后:" + credit.getName() + "===" + credit.get(obj)); }}運行結果
通過反射獲取類的方法
import reflect.Student;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Main { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //1.獲取Class對象 //獲取類對象的第一種方式 Class stu = Class.forName("reflect.Student"); System.out.println("獲取類的對象1::"+stu); //2.獲取所有公有方法 //獲取一個對象 Object obj = stu.getConstructor().newInstance(); System.out.println("***************獲取所有的”公有“方法*******************"); Method[] methodArray = stu.getMethods(); for(Method m : methodArray){ System.out.println("獲取所有公有方法"+m); } System.out.println("***************獲取所有的方法,包括私有的*******************"); methodArray = stu.getDeclaredMethods(); for(Method m : methodArray){ System.out.println("獲取所有的方法,包括私有的"+m); } System.out.println("***************獲取公有的getName()方法*******************"); Method m = stu.getMethod("getName",String.class); System.out.println("獲取公有的getName"+m); //設計值 m.invoke(obj, "小"); System.out.println("***************獲取私有的getCredit()方法******************"); m = stu.getDeclaredMethod("getCredit",int.class); System.out.println("獲取私有的getCredit()方法:"+m); m.setAccessible(true);//解除私有限定 Object result = m.invoke(obj, 20);//需要兩個參數,一個是要調用的對象(獲取有反射),一個是實參 System.out.println("返回值學分:" + result); }}反射方法運行結果:
使用到的異常:
ClassNotFoundException? :?沒有找到類的異常NoSuchMethodException: 沒有找到方法的異常IllegalAccessException : 沒有訪問權限的異常InvocationTargetException :包裝由調用方法或構造方法所拋出異常的受查異常InstantiationException: 指不能實例化某個對象與Java反射相關的類如下:
動態代理的時候也可以用到反射等。比如aop。
總結
以上是生活随笔為你收集整理的java反射机制原理详解_java反射机制的详细讲解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python定积分_python定积分
- 下一篇: 4+5的值是python_Python基