最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 反射機制原理與用法詳解

 更新時間:2019年11月05日 11:13:16   作者:蒼青浪  
這篇文章主要介紹了Java 反射機制原理與用法,結(jié)合實例形式詳細分析了Java反射機制的相關(guān)概念、原理、基本使用方法及操作注意事項,需要的朋友可以參考下

本文實例講述了Java 反射機制原理與用法。分享給大家供大家參考,具體如下:

反射反射,程序員的快樂!

1、什么是反射?

Java反射就是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意方法和屬性;并且能改變它的屬性。而這也是Java被視為動態(tài)(或準動態(tài),為啥要說是準動態(tài),因為一般而言的動態(tài)語言定義是程序運行時,允許改變程序結(jié)構(gòu)或變量類型,這種語言稱為動態(tài)語言。從這個觀點看,Perl,Python,Ruby是動態(tài)語言,C++,Java,C#不是動態(tài)語言。)語言的一個關(guān)鍵性質(zhì)。

2、反射能做什么?

我們知道反射機制允許程序在運行時取得任何一個已知名稱的class的內(nèi)部信息,包括包括其modifiers(修飾符),fields(屬性),methods(方法)等,并可于運行時改變fields內(nèi)容或調(diào)用methods。那么我們便可以更靈活的編寫代碼,代碼可以在運行時裝配,無需在組件之間進行源代碼鏈接,降低代碼的耦合度;還有動態(tài)代理的實現(xiàn)等等;但是需要注意的是反射使用不當會造成很高的資源消耗!

3、反射的具體實現(xiàn)

下面是一個基本的類 Person

package com.ys.reflex;
public class Person {
  //私有屬性
  private String name = "Tom";
  //公有屬性
  public int age = 18;
  //構(gòu)造方法
  public Person() {  
  }
  //私有方法
  private void say(){
    System.out.println("private say()...");
  }
  //公有方法
  public void work(){
    System.out.println("public work()...");
  }
}

①、得到 Class 的三種方式

//1、通過對象調(diào)用 getClass() 方法來獲取,通常應用在:比如你傳過來一個 Object
// 類型的對象,而我不知道你具體是什么類,用這種方法
Person p1 = new Person();
Class c1 = p1.getClass();
//2、直接通過 類名.class 的方式得到,該方法最為安全可靠,程序性能更高
// 這說明任何一個類都有一個隱含的靜態(tài)成員變量 class
Class c2 = Person.class;
//3、通過 Class 對象的 forName() 靜態(tài)方法來獲取,用的最多,
//  但可能拋出 ClassNotFoundException 異常
Class c3 = Class.forName("com.ys.reflex.Person");

需要注意的是:一個類在 JVM 中只會有一個 Class 實例,即我們對上面獲取的 c1,c2,c3進行 equals 比較,發(fā)現(xiàn)都是true

②、通過 Class 類獲取成員變量、成員方法、接口、超類、構(gòu)造方法等

查閱 API 可以看到 Class 有很多方法:

  • getName():獲得類的完整名字。
  • getFields():獲得類的public類型的屬性。
  • getDeclaredFields():獲得類的所有屬性。包括private 聲明的和繼承類
  • getMethods():獲得類的public類型的方法。
  • getDeclaredMethods():獲得類的所有方法。包括private 聲明的和繼承類
  • getMethod(String name, Class[] parameterTypes):獲得類的特定方法,name參數(shù)指定方法的名字,parameterTypes 參數(shù)指定方法的參數(shù)類型。
  • getConstructors():獲得類的public類型的構(gòu)造方法。
  • getConstructor(Class[] parameterTypes):獲得類的特定構(gòu)造方法,parameterTypes 參數(shù)指定構(gòu)造方法的參數(shù)類型。
  • newInstance():通過類的不帶參數(shù)的構(gòu)造方法創(chuàng)建這個類的一個對象。

我們通過一個例子來綜合演示上面的方法:

//獲得類完整的名字
String className = c2.getName();
System.out.println(className);//輸出com.ys.reflex.Person
//獲得類的public類型的屬性。
Field[] fields = c2.getFields();
for(Field field : fields){
  System.out.println(field.getName());//age
}
//獲得類的所有屬性。包括私有的
Field [] allFields = c2.getDeclaredFields();
for(Field field : allFields){
  System.out.println(field.getName());//name  age
}
//獲得類的public類型的方法。這里包括 Object 類的一些方法
Method [] methods = c2.getMethods();
for(Method method : methods){
  System.out.println(method.getName());//work waid equls toString hashCode等
}
//獲得類的所有方法。
Method [] allMethods = c2.getDeclaredMethods();
for(Method method : allMethods){
  System.out.println(method.getName());//work say
}
//獲得指定的屬性
Field f1 = c2.getField("age");
System.out.println(f1);
//獲得指定的私有屬性
Field f2 = c2.getDeclaredField("name");
//啟用和禁用訪問安全檢查的開關(guān),值為 true,則表示反射的對象在使用時應該取消 java 語言的訪問檢查;反之不取消
f2.setAccessible(true);
System.out.println(f2);
//創(chuàng)建這個類的一個對象
Object p2 = c2.newInstance();
//將 p2 對象的 f2 屬性賦值為 Bob,f2 屬性即為 私有屬性 name
f2.set(p2,"Bob");
//使用反射機制可以打破封裝性,導致了java對象的屬性不安全。 
System.out.println(f2.get(p2)); //Bob
//獲取構(gòu)造方法
Constructor [] constructors = c2.getConstructors();
for(Constructor constructor : constructors){
  System.out.println(constructor.toString());//public com.ys.reflex.Person()
}

4、根據(jù)反射獲取父類屬性

父類 Parent.java

public class Parent {
  public String publicField = "parent_publicField";
  protected String protectField = "parent_protectField";
  String defaultField = "parent_defaultField";
  private String privateField = "parent_privateField";
}

子類 Son.java

public class Son extends Parent {
}
public class ReflectionTest {
  @Test
  public void testGetParentField() throws Exception{
    Class c1 = Class.forName("com.ys.model.Son");
    //獲取父類私有屬性值
    System.out.println(getFieldValue(c1.newInstance(),"privateField"));
  }
  public static Field getDeclaredField(Object obj,String fieldName) {
    Field field = null;
    Class c = obj.getClass();
    for(; c != Object.class ; c = c.getSuperclass()){
      try {
        field = c.getDeclaredField(fieldName);
        field.setAccessible(true);
        return field;
      }catch (Exception e){
        //這里甚么都不要做!并且這里的異常必須這樣寫,不能拋出去。
        //如果這里的異常打印或者往外拋,則就不會執(zhí)行c = c.getSuperclass(),最后就不會進入到父類中了
      }
    }
    return null;
  }
  public static Object getFieldValue(Object object,String fieldName) throws Exception{
    Field field = getDeclaredField(object,fieldName);
    return field.get(object);
  }
}

通過執(zhí)行上述代碼,我們獲得了父類的私有屬性值,這里要注意的是直接通過反射獲取子類的對象是不能得到父類的屬性值的,必須根據(jù)反射獲得的子類 Class 對象在調(diào)用  getSuperclass() 方法獲取父類對象,然后在通過父類對象去獲取父類的屬性值。

5、反射總結(jié)

靈活使用反射能讓我們代碼更加靈活,這里比如JDBC原生代碼注冊驅(qū)動,hibernate 的實體類,Spring 的 AOP等等都有反射的實現(xiàn)。但是凡事都有兩面性,反射也會消耗系統(tǒng)的性能,增加復雜性等,合理使用才是真!

更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O計入門與進階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總

希望本文所述對大家java程序設計有所幫助。

相關(guān)文章

  • Java+Eclipse+Selenium環(huán)境搭建的方法步驟

    Java+Eclipse+Selenium環(huán)境搭建的方法步驟

    這篇文章主要介紹了Java+Eclipse+Selenium環(huán)境搭建的方法步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-06-06
  • Java值得使用Lambda的8個場景合集

    Java值得使用Lambda的8個場景合集

    可能對不少人來說,Lambda顯得陌生又復雜,覺得Lambda會導致代碼可讀性下降,但畢竟2023年了,JDK都出了那么多新版本,是時候試試Lambda了
    2023-08-08
  • Spring Boot 開發(fā)環(huán)境熱部署詳細教程

    Spring Boot 開發(fā)環(huán)境熱部署詳細教程

    這篇文章主要介紹了Spring Boot 開發(fā)環(huán)境熱部署,本文給大家介紹了Spring Boot 開發(fā)環(huán)境熱部署的原理及快速配置方法,通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • SpringBoot應用部署到外置Tomcat的實現(xiàn)

    SpringBoot應用部署到外置Tomcat的實現(xiàn)

    SpringBoot內(nèi)置tomcat使用很方便,本文主要介紹了SpringBoot應用部署到外置Tomcat的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-07-07
  • java?常規(guī)輪詢長輪詢Long?polling實現(xiàn)示例詳解

    java?常規(guī)輪詢長輪詢Long?polling實現(xiàn)示例詳解

    這篇文章主要為大家介紹了java?常規(guī)輪詢長輪詢Long?polling實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • java實現(xiàn)二維數(shù)組轉(zhuǎn)置的方法示例

    java實現(xiàn)二維數(shù)組轉(zhuǎn)置的方法示例

    這篇文章主要介紹了java實現(xiàn)二維數(shù)組轉(zhuǎn)置的方法,結(jié)合實例形式詳細分析了java二維數(shù)組轉(zhuǎn)置的原理、實現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2017-10-10
  • RestTemplat中關(guān)于getForobject方法的使用

    RestTemplat中關(guān)于getForobject方法的使用

    這篇文章主要介紹了RestTemplat中關(guān)于getForobject方法的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java字節(jié)碼框架ASM的深入學習

    java字節(jié)碼框架ASM的深入學習

    這篇文章主要給大家介紹了java中字節(jié)碼框架ASM的相關(guān)資料,文中介紹的非常詳細,相信對大家的理解和學習具有一定的參考借鑒價值,有需要的朋友們下面來一起學習學習吧。
    2017-01-01
  • intellij idea 2021.2 打包并上傳運行spring boot項目的詳細過程(spring boot 2.5.4)

    intellij idea 2021.2 打包并上傳運行spring boot項目的詳細過程(spring boot 2

    這篇文章主要介紹了intellij idea 2021.2 打包并上傳運行一個spring boot項目(spring boot 2.5.4),本文通過圖文并茂的形式給大家介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • 一篇帶你解析入門LongAdder源碼

    一篇帶你解析入門LongAdder源碼

    LongAdder類是JDK1.8新增的一個原子性操作類。AtomicLong通過CAS算法提供了非阻塞的原子性操作,因為非常搞并發(fā)的請求下AtomicLong的性能是不能讓人接受的
    2021-06-06

最新評論

内江市| 惠安县| 平阴县| 鹿邑县| 达尔| 玉环县| 伊吾县| 凌源市| 益阳市| 师宗县| 宕昌县| 平谷区| 邢台县| 西吉县| 汪清县| 西青区| 满城县| 曲沃县| 五峰| 和静县| 陕西省| 白朗县| 房产| 盖州市| 米脂县| 聂拉木县| 赤城县| 隆德县| 茂名市| 固始县| 庐江县| 务川| 潜江市| 上杭县| 肃宁县| 宁南县| 桐庐县| 息烽县| 高安市| 仙居县| 新津县|