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

詳解Java中的Reflection反射和暴力反射

 更新時間:2023年06月16日 11:14:11   作者:魚找水需要時間  
本文主要介紹了詳解Java中的Reflection反射和暴力反射,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1. 反射(Reflection)的概念

1.1 反射的出現(xiàn)背景

Java程序中,所有的對象都有兩種類型:編譯時類型運行時類型,而很多時候?qū)ο蟮木幾g時類型和運行時類型不一致

例如:

Object obj = new String("hello");
obj.getClass()

如上:某些變量或形參的聲明類型是Object類型,但是程序卻需要調(diào)用該對象運行時類型的方法,該方法不是Object中的方法,那么如何解決呢?

解決這個問題,有兩種方案:

方案1:在編譯和運行時都完全知道類型的具體信息,在這種情況下,我們可以直接先使用instanceof運算符進行判斷,再利用強制類型轉(zhuǎn)換符將其轉(zhuǎn)換成運行時類型的變量即可。

方案2:編譯時根本無法預知該對象和類的真實信息,程序只能依靠運行時信息來發(fā)現(xiàn)該對象和類的真實信息,這就必須使用反射。

1.2 反射概述

Reflection(反射)是被視為動態(tài)語言的關(guān)鍵,反射機制允許程序在運行期間借助于Reflection API取得任何類的內(nèi)部信息,并能直接操作任意對象的內(nèi)部屬性及方法。

加載完類之后,在堆內(nèi)存的方法區(qū)中就產(chǎn)生了一個Class類型的對象(一個類只有一個Class對象),這個對象就包含了完整的類的結(jié)構(gòu)信息。此時就可以通過這個對象看到類的結(jié)構(gòu)。這個對象就像一面鏡子,透過這個鏡子看到類的結(jié)構(gòu),所以,我們形象的稱之為:反射。

從內(nèi)存加載上看反射:

1.3 Java反射機制研究及應用

Java反射機制提供的功能:

  • 在運行時判斷任意一個對象所屬的類
  • 在運行時構(gòu)造任意一個類的對象
  • 在運行時判斷任意一個類所具有的成員變量和方法
  • 在運行時獲取泛型信息
  • 在運行時調(diào)用任意一個對象的成員變量和方法
  • 在運行時處理注解
  • 生成動態(tài)代理

1.4 反射相關(guān)的主要API

java.lang.Class:代表一個類
java.lang.reflect.Method:代表類的方法
java.lang.reflect.Field:代表類的成員變量
java.lang.reflect.Constructor:代表類的構(gòu)造器
......

1.5 反射的優(yōu)缺點

優(yōu)點:

  • 提高了Java程序的靈活性和擴展性,降低了耦合性,提高自適應能力
  • 允許程序創(chuàng)建和控制任何類的對象,無需提前硬編碼目標類

缺點:

  • 反射的性能較低。
    • 反射機制主要應用在對靈活性和擴展性要求很高的系統(tǒng)框架上
  • 反射會模糊程序內(nèi)部邏輯,可讀性較差。

2. Class類并獲取Class實例

要想解剖一個類,必須先要獲取到該類的Class對象。而剖析一個類或用反射解決具體的問題就是使用相關(guān)API:

java.lang.Classjava.lang.reflect.*

所以,Class對象是反射的根源。

2.1 理解Class

2.1.1 理論上

在Object類中定義了以下的方法,此方法將被所有子類繼承

public final Class getClass()

以上的方法返回值的類型是一個Class類,此類是Java反射的源頭,實際上所謂反射從程序的運行結(jié)果來看也很好理解,即:可以通過對象反射求出類的名稱

對象照鏡子后可以得到的信息:某個類的屬性、方法和構(gòu)造器、某個類到底實現(xiàn)了哪些接口。對于每個類而言,JRE 都為其保留一個不變的 Class 類型的對象。一個 Class 對象包含了特定某個結(jié)構(gòu)(class/interface/enum/annotation/primitive type/void/[])的有關(guān)信息。

  • Class本身也是一個類
  • Class 對象只能由系統(tǒng)建立對象
  • 一個加載的類在 JVM 中只會有一個Class實例
  • 一個Class對象對應的是一個加載到JVM中的一個.class文件
  • 每個類的實例都會記得自己是由哪個 Class 實例所生成
  • 通過Class可以完整地得到一個類中的所有被加載的結(jié)構(gòu)
  • Class類是Reflection的根源,針對任何你想動態(tài)加載、運行的類,唯有先獲得相應的Class對象

2.1.2 內(nèi)存結(jié)構(gòu)上

說明:上圖中字符串常量池在JDK6中存儲在方法區(qū);JDK7及以后,存儲在堆空間。

2.2 獲取Class類的實例(四種方法)

方式1:要求編譯期間已知類型

前提:若已知具體的類,通過類的class屬性獲取,該方法最為安全可靠,程序性能最高

實例:

Class clazz = String.class;

方式2:獲取對象的運行時類型

前提:已知某個類的實例,調(diào)用該實例的getClass()方法獲取Class對象

實例:

Class clazz = "www.example.com".getClass();

方式3:可以獲取編譯期間未知的類型

前提:已知一個類的全類名,且該類在類路徑下,可通過Class類的靜態(tài)方法forName()獲取,可能拋出ClassNotFoundException

實例:

Class clazz = Class.forName("java.lang.String");

方式4:其他方式(不做要求)

前提:可以用系統(tǒng)類加載對象或自定義加載器對象加載指定路徑下的類型

實例:

ClassLoader cl = this.getClass().getClassLoader();
Class clazz4 = cl.loadClass("類的全類名");

再舉例:

public class GetClassObject {
    @Test
    public void test01() throws ClassNotFoundException{
        Class c1 = GetClassObject.class;
        GetClassObject obj = new GetClassObject();
        Class c2 = obj.getClass();
        Class c3 = Class.forName("com.example.classtype.GetClassObject");
        Class c4 = ClassLoader.getSystemClassLoader().loadClass("com.example.classtype.GetClassObject");
        System.out.println("c1 = " + c1);
        System.out.println("c2 = " + c2);
        System.out.println("c3 = " + c3);
        System.out.println("c4 = " + c4);
        System.out.println(c1 == c2);
        System.out.println(c1 == c3);
        System.out.println(c1 == c4);
    }
}

2.3 哪些類型可以有Class對象

簡而言之,所有Java類型!

(1)class:外部類,成員(成員內(nèi)部類,靜態(tài)內(nèi)部類),局部內(nèi)部類,匿名內(nèi)部類
(2)interface:接口
(3)[]:數(shù)組
(4)enum:枚舉
(5)annotation:注解@interface
(6)primitive type:基本數(shù)據(jù)類型
(7)void

舉例:

Class c1 = Object.class;
Class c2 = Comparable.class;
Class c3 = String[].class;
Class c4 = int[][].class;
Class c5 = ElementType.class;
Class c6 = Override.class;
Class c7 = int.class;
Class c8 = void.class;
Class c9 = Class.class;
int[] a = new int[10];
int[] b = new int[100];
Class c10 = a.getClass();
Class c11 = b.getClass();
// 只要元素類型與維度一樣,就是同一個Class
System.out.println(c10 == c11);

2.4 Class類的常用方法

方法名功能說明
static Class forName(String name)返回指定類名 nameClass 對象
Object newInstance()調(diào)用缺省構(gòu)造函數(shù),返回該Class對象的一個實例
getName()返回此Class對象所表示的實體(類、接口、數(shù)組類、基本類型或void)名稱
Class getSuperClass()返回當前Class對象的父類的Class對象
Class [] getInterfaces()獲取當前Class對象的接口
ClassLoader getClassLoader()返回該類的類加載器
Class getSuperclass()返回表示此Class所表示的實體的超類的Class
Constructor[] getConstructors()返回一個包含某些Constructor對象的數(shù)組
Field[] getDeclaredFields()返回Field對象的一個數(shù)組
Method getMethod(String name,Class … paramTypes)返回一個Method對象,此對象的形參類型為paramType

舉例:

String str = "test4.Person";
Class clazz = Class.forName(str);
Object obj = clazz.newInstance();
Field field = clazz.getField("name");
field.set(obj, "Peter");
Object name = field.get(obj);
System.out.println(name);
//注:test4.Person是test4包下的Person類

到此這篇關(guān)于詳解Java中的Reflection反射和暴力反射的文章就介紹到這了,更多相關(guān)Java Reflection反射和暴力反射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot項目使用Log4j2+SLF4J構(gòu)建日志的方法步驟

    SpringBoot項目使用Log4j2+SLF4J構(gòu)建日志的方法步驟

    在現(xiàn)代軟件開發(fā)中,日志記錄是一個重要的部分,Spring Boot配置了多種日志框架,這篇文章主要介紹了SpringBoot項目使用Log4j2+SLF4J構(gòu)建日志的方法步驟,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-11-11
  • 基于spring@aspect注解的aop實現(xiàn)過程代碼實例

    基于spring@aspect注解的aop實現(xiàn)過程代碼實例

    這篇文章主要介紹了基于spring@aspect注解的aop實現(xiàn)過程代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • RocketMQ?Broker實現(xiàn)高可用高并發(fā)的消息中轉(zhuǎn)服務(wù)

    RocketMQ?Broker實現(xiàn)高可用高并發(fā)的消息中轉(zhuǎn)服務(wù)

    RocketMQ消息代理(Broker)是一種高可用、高并發(fā)的消息中轉(zhuǎn)服務(wù),能夠接收并存儲生產(chǎn)者發(fā)送的消息,并將消息發(fā)送給消費者。它具有多種消息存儲模式和消息傳遞模式,支持水平擴展和故障轉(zhuǎn)移等特性,可以為分布式應用提供可靠的消息傳遞服務(wù)
    2023-04-04
  • Springmvc的運行流程圖文詳解

    Springmvc的運行流程圖文詳解

    今天小編就為大家分享一篇關(guān)于Springmvc的運行流程圖文詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java超詳細透徹講解static

    Java超詳細透徹講解static

    static關(guān)鍵字基本概念我們可以一句話來概括:方便在沒有創(chuàng)建對象的情況下來進行調(diào)用。也就是說:被static關(guān)鍵字修飾的不需要創(chuàng)建對象去調(diào)用,直接根據(jù)類名就可以去訪問,讓我們來了解一下你可能還不知道情況
    2022-05-05
  • java稀疏數(shù)組的示例代碼

    java稀疏數(shù)組的示例代碼

    這篇文章主要介紹了java稀疏數(shù)組,稀疏數(shù)組,記錄一共有幾行幾列,有多少個不同值,把具有不同值的元素和行里了及值記錄在一個小規(guī)模的數(shù)組中,從而縮小程序的規(guī)模,對java稀疏數(shù)組相關(guān)知識感興趣的朋友一起看看吧
    2022-07-07
  • java 創(chuàng)建線程的幾種方式

    java 創(chuàng)建線程的幾種方式

    本文主要介紹了java中創(chuàng)建線程的幾種方式。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • Java第三方庫JodaTime的具體使用

    Java第三方庫JodaTime的具體使用

    本文主要介紹了Java第三方庫JodaTime的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Java對象和Json文本轉(zhuǎn)換工具類的實現(xiàn)

    Java對象和Json文本轉(zhuǎn)換工具類的實現(xiàn)

    Json?是一個用于Java對象和Json文本相互轉(zhuǎn)換的工具類,本文主要介紹了Java對象和Json文本轉(zhuǎn)換工具類,具有一定的參考價值,感興趣的可以了解一下
    2022-03-03
  • Spring Data JPA實現(xiàn)分頁Pageable的實例代碼

    Spring Data JPA實現(xiàn)分頁Pageable的實例代碼

    本篇文章主要介紹了Spring Data JPA實現(xiàn)分頁Pageable的實例代碼,具有一定的參考價值,有興趣的可以了解一下
    2017-07-07

最新評論

洛隆县| 清远市| 威宁| 灵石县| 芦山县| 乐亭县| 清流县| 台江县| 河东区| 新巴尔虎左旗| 社旗县| 佛坪县| 高雄市| 牙克石市| 成武县| 黎川县| 长乐市| 晋中市| 大名县| 阿克苏市| 扎赉特旗| 喜德县| 名山县| 吴忠市| 昂仁县| 曲松县| 监利县| 定兴县| 尼木县| 临泉县| 伽师县| 榆中县| 龙海市| 邢台县| 湖北省| 确山县| 抚宁县| 鹰潭市| 桑日县| 通辽市| 达州市|