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

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

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

1. 反射(Reflection)的概念

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

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

例如:

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

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

解決這個(gè)問題,有兩種方案:

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

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

1.2 反射概述

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

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

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

1.3 Java反射機(jī)制研究及應(yīng)用

Java反射機(jī)制提供的功能:

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

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

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

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

優(yōu)點(diǎn):

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

缺點(diǎn):

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

2. Class類并獲取Class實(shí)例

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

java.lang.Classjava.lang.reflect.*

所以,Class對(duì)象是反射的根源。

2.1 理解Class

2.1.1 理論上

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

public final Class getClass()

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

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

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

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

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

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

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

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

實(shí)例:

Class clazz = String.class;

方式2:獲取對(duì)象的運(yùn)行時(shí)類型

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

實(shí)例:

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

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

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

實(shí)例:

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

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

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

實(shí)例:

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對(duì)象

簡而言之,所有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();
// 只要元素類型與維度一樣,就是同一個(gè)Class
System.out.println(c10 == c11);

2.4 Class類的常用方法

方法名功能說明
static Class forName(String name)返回指定類名 nameClass 對(duì)象
Object newInstance()調(diào)用缺省構(gòu)造函數(shù),返回該Class對(duì)象的一個(gè)實(shí)例
getName()返回此Class對(duì)象所表示的實(shí)體(類、接口、數(shù)組類、基本類型或void)名稱
Class getSuperClass()返回當(dāng)前Class對(duì)象的父類的Class對(duì)象
Class [] getInterfaces()獲取當(dāng)前Class對(duì)象的接口
ClassLoader getClassLoader()返回該類的類加載器
Class getSuperclass()返回表示此Class所表示的實(shí)體的超類的Class
Constructor[] getConstructors()返回一個(gè)包含某些Constructor對(duì)象的數(shù)組
Field[] getDeclaredFields()返回Field對(duì)象的一個(gè)數(shù)組
Method getMethod(String name,Class … paramTypes)返回一個(gè)Method對(duì)象,此對(duì)象的形參類型為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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

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

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

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

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

    Springmvc的運(yùn)行流程圖文詳解

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

    Java超詳細(xì)透徹講解static

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

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

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

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

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

    Java第三方庫JodaTime的具體使用

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

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

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

    Spring Data JPA實(shí)現(xiàn)分頁P(yáng)ageable的實(shí)例代碼

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

最新評(píng)論

乌什县| 德江县| 西青区| 临夏市| 云浮市| 太康县| 百色市| 青州市| 观塘区| 枝江市| 金华市| 汽车| 左云县| 南和县| 石城县| 黎川县| 灵石县| 龙里县| 眉山市| 静安区| 松桃| 宜兰县| 兴义市| 宣城市| 抚顺市| 旺苍县| 淮南市| 西昌市| 郎溪县| 泽库县| 沂南县| 沈阳市| 广宁县| 密云县| 即墨市| 赤城县| 襄城县| 凤翔县| 彰武县| 鄄城县| 白水县|