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