国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java反射、代理機(jī)制

這篇具有很好參考價(jià)值的文章主要介紹了Java反射、代理機(jī)制。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1.什么是反射

官方解釋:反射允許對(duì)封裝類的字段、方法和構(gòu)造方法的信息進(jìn)行編程訪問(wèn)。

虛擬機(jī)加載類文件后,會(huì)在方法區(qū)生成一個(gè)類對(duì)象,包含了類的結(jié)構(gòu)信息,如字段、方法、構(gòu)造方法等。反射是一種能夠在程序運(yùn)行時(shí)動(dòng)態(tài)訪問(wèn)、修改類對(duì)象中任意屬性的機(jī)制(包括private屬性)。

Java 反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意方法和屬性;這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為 Java 語(yǔ)言的反射機(jī)制。簡(jiǎn)單來(lái)說(shuō),反射機(jī)制指的是程序在運(yùn)行時(shí)能夠獲取自身的信息。在 Java 中,只要給定類的名字,就可以通過(guò)反射機(jī)制來(lái)獲得類的所有信息。

如果說(shuō)大家研究過(guò)框架的底層原理或者咱們自己寫(xiě)過(guò)框架的話,一定對(duì)反射這個(gè)概念不陌生。

反射之所以被稱為框架的靈魂,主要是因?yàn)樗x予了我們?cè)谶\(yùn)行時(shí)分析類以及執(zhí)行類中方法的能力。

通過(guò)反射你可以獲取任意一個(gè)類的所有屬性和方法,你還可以調(diào)用這些方法和屬性。

獲取類對(duì)象的四種方式


1.通過(guò)對(duì)象獲取到類對(duì)象.getClass();
Class personClass = person.getClass();
2.通過(guò) Class.forName()傳入類的全路徑獲取;裝入類,并做類的靜態(tài)初始化,返回Class的對(duì)象
Class personClass = Class.forName("全類名");
3.通過(guò)類屬性 ClassName.Class獲取類對(duì)象;
Class personClass = Person.Class;
4.通過(guò)ClassLoader.getSystemClassLoader().loadClass("全類名");通過(guò)類加載器獲取 Class 對(duì)象不會(huì)進(jìn)行初始化,意味著不進(jìn)行包括初始化等一系列步驟,靜態(tài)代碼塊和靜態(tài)對(duì)象不會(huì)得到執(zhí)行

注意:全類名是包名+類名,一般是程序src目錄下的包名+類名。

類對(duì)象中描述各個(gè)部分的對(duì)象:

  1. Class:描述整個(gè)類的對(duì)象
  2. Constructor:描述構(gòu)造方法的對(duì)象
            Class clazz = Class.forName("Person");
            //獲取類的所有構(gòu)造方法
            Constructor[] constructorAll = clazz.getDeclaredConstructors();
            for(Constructor c: constructorAll){
                System.out.println(c);
            }
    
            Constructor constructor1 = clazz.getDeclaredConstructor();
            Constructor constructor2 = clazz.getDeclaredConstructor(String.class);
            System.out.println(constructor1);
            System.out.println(constructor2);
    
            //可以獲取構(gòu)造方法中的一些內(nèi)容
            int modifiers = constructor1.getModifiers();
            System.out.println(modifiers);
    
            int parameterCount = constructor1.getParameterCount();
            System.out.println(parameterCount);
    
            Parameter[] parameters = constructor2.getParameters();
            for(Parameter p: parameters){
                System.out.println(p);
            }
    
            //使用構(gòu)造方法創(chuàng)建對(duì)象
            Person person = (Person) constructor1.newInstance();
            System.out.println(person);
  3. Field:描述成員變量的對(duì)象
            Class clazz = Class.forName("Person");
            //獲取私有/非私有屬性
            Field[] fields = clazz.getDeclaredFields();
            for(Field f: fields){
                System.out.println(f);
            }
    
            Field field = clazz.getDeclaredField("name");
            System.out.println(field);
    
            //獲取權(quán)限修飾符
            int modifiers = field.getModifiers();
            System.out.println(modifiers);
    
            //獲取數(shù)據(jù)類型
            String value = field.getName();
            System.out.println( value);
    
  4. Method:描述成員方法的對(duì)象。

2.反射的功能

1.獲取一個(gè)類里面所有的信息和其他業(yè)務(wù)邏輯。

2.結(jié)合配置文件,動(dòng)態(tài)的創(chuàng)建對(duì)象并調(diào)用方法。

1、Java反射機(jī)制的核心是在程序運(yùn)行時(shí)動(dòng)態(tài)加載類并獲取類的詳細(xì)信息,從而操作類或?qū)ο蟮膶傩院头椒ā1举|(zhì)是JVM得到class對(duì)象之后,再通過(guò)class對(duì)象進(jìn)行反編譯,從而獲取對(duì)象的各種信息。

2、Java屬于先編譯再運(yùn)行的語(yǔ)言,程序中對(duì)象的類型在編譯期就確定下來(lái)了,而當(dāng)程序在運(yùn)行時(shí)可能需要?jiǎng)討B(tài)加載某些類,這些類因?yàn)橹坝貌坏?,所以沒(méi)有被加載到JVM。通過(guò)反射,可以在運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建對(duì)象并調(diào)用其屬性,不需要提前在編譯期知道運(yùn)行的對(duì)象是誰(shuí)。

3.序列化、反序列化

Serialization(序列化)是一種將對(duì)象以一連串的字節(jié)描述的過(guò)程;反序列化deserialization是一種將這些字節(jié)重建成一個(gè)對(duì)象的過(guò)程。將程序中的對(duì)象,放入文件中保存就是序列化,將文件中的字節(jié)碼重新轉(zhuǎn)成對(duì)象就是反序列化。

ObjectOutputStream 類用來(lái)序列化一個(gè)對(duì)象,可將對(duì)象序列化到一個(gè)文件中。

注意: 當(dāng)序列化一個(gè)對(duì)象到文件時(shí), 按照 Java 的標(biāo)準(zhǔn)約定是給文件一個(gè) .ser 擴(kuò)展名。


public class Main {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
? ? ? ? //創(chuàng)建文件輸出流對(duì)象
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\Serializable\\Person.ser");
? ? ? ? //創(chuàng)建序列化對(duì)象
        Person person = new Person("name",22,"女","black","boy");
? ? ? ? //創(chuàng)建對(duì)象輸出流
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
? ? ? ? //將對(duì)象序列化
        objectOutputStream.writeObject(person);
? ? ? ? //創(chuàng)建文件輸入流對(duì)象
        FileInputStream fileInputStream = new FileInputStream("D:\\Serializable\\Person.ser");
? ? ? ? //創(chuàng)建對(duì)象輸入流
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
? ? ? ? //反序列化
        Person person1 = (Person) objectInputStream.readObject();
        System.out.println(person1);
    }
}

三、序列化和反序列化的注意點(diǎn):

1.序列化時(shí),只對(duì)對(duì)象的屬性進(jìn)行保存。

2.當(dāng)一個(gè)父類實(shí)現(xiàn)序列化,子類自動(dòng)實(shí)現(xiàn)序列化,不需要顯式實(shí)現(xiàn)Serializable接口。

3.當(dāng)一個(gè)對(duì)象的實(shí)例變量引用其他對(duì)象,序列化該對(duì)象時(shí)也把引用對(duì)象進(jìn)行序列化。

4.聲明為static和transient類型的成員數(shù)據(jù)不能被序列化。因?yàn)閟tatic代表類的狀態(tài),transient代表對(duì)象的臨時(shí)數(shù)據(jù)。

5.Java有很多基礎(chǔ)類已經(jīng)實(shí)現(xiàn)了serializable接口,比如String,Vector等。但是也有一些沒(méi)有實(shí)現(xiàn)serializable接口的。

6.序列號(hào)id,用于標(biāo)識(shí)序列號(hào)對(duì)象的版本,在反序列化的過(guò)程中,會(huì)使用序列化id來(lái)檢查序列化對(duì)象的版本與當(dāng)前類的版本是否匹配。

功能

  • 對(duì)象隨著程序的運(yùn)行而創(chuàng)建,程序結(jié)束對(duì)象就銷毀,序列化可以讓對(duì)象持久的保持在內(nèi)存中

  • 可以在進(jìn)程之間進(jìn)行對(duì)象傳輸

4.動(dòng)態(tài)代理

無(wú)侵入的為對(duì)象的方法增加新功能。

動(dòng)態(tài)代理的實(shí)現(xiàn)步驟:

  1. 定義接口,并定義要在代理對(duì)象中實(shí)現(xiàn)的方法(包括返回類型、參數(shù)列表、方法名)
  2. 創(chuàng)建一個(gè)實(shí)現(xiàn)InvocationHandler接口的類,并重寫(xiě)invoke方法,invoke方法在代理對(duì)象調(diào)用方法時(shí)觸發(fā),并允許在方法調(diào)用前后增加額外的邏輯。
  3. 使用Proxy類創(chuàng)建代理對(duì)象java.lang.reflect.Proxy類的靜態(tài)方法newProxyInstace來(lái)創(chuàng)建代理對(duì)象,該方法有三個(gè)參數(shù)。參數(shù)1:加載代理類的類加載器;參數(shù)2:目標(biāo)對(duì)象實(shí)現(xiàn)的接口;參數(shù)3:InvocationHandler對(duì)象,表示實(shí)現(xiàn)invoke方法的對(duì)象。
  4. 調(diào)用代理對(duì)象的方法,當(dāng)代理對(duì)象的方法被調(diào)用時(shí),invoke方法會(huì)被觸發(fā)。

public class Person implements IPerson{
    private String name;

    public Person(){

    }

    public Person(String name){
        this.name = name;
    }

    @Override
    public String eat(String thing){
        System.out.println(this.name+"正在吃"+thing);
        return thing;
    }

    @Override
    public void run(){
        System.out.println(this.name+"正在run");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public interface IPerson {
    //把需要代理的方法定義在接口當(dāng)中
    public abstract String eat(String name);
    public abstract void run();
}

public class ProxyUtil {
    /**
     *為給定的對(duì)象生成一個(gè)代理對(duì)象
     * @param person
     */
    public static IPerson createProxy(Person person) {
        /**
         * 參數(shù)1:指定類加載器,去加載生成的代理類
         * 參數(shù)2:指定接口,這個(gè)接口用于指定生成的代理長(zhǎng)什么,也就是有哪些方法
         * 參數(shù)3:用來(lái)指定生成的代理對(duì)象要干什么事情
         */

        IPerson iPerson = (IPerson) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader()
                , new Class[]{IPerson.class}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /**
                         * 參數(shù)1:代理的對(duì)象
                         * 參數(shù)2:要運(yùn)行的方法
                         * 參數(shù)3:調(diào)用方法時(shí)傳遞的實(shí)參
                         */
                        if("eat".equals(method.getName())){
                            System.out.println("拿筷子");
                            System.out.println("拿碗");
                        }else if("run".equals(method.getName())){
                            System.out.println("帶水");
                            System.out.println("穿褲子");
                        }

                        return method.invoke(person,args);
                    }
                });
        return iPerson;
    }
}

? 實(shí)現(xiàn)原理:通過(guò)代理類生成字節(jié)碼文件,使用類加載器將文件加載到內(nèi)存,最終創(chuàng)建代理對(duì)象。

注意:動(dòng)態(tài)的生成字節(jié)碼文件,是在運(yùn)行時(shí)發(fā)生的。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-690513.html

到了這里,關(guān)于Java反射、代理機(jī)制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java動(dòng)態(tài)代理、反射

    Java動(dòng)態(tài)代理、反射

    動(dòng)態(tài)代理就是無(wú)侵入式的給代碼增加新的功能,通過(guò)接口保證后面的對(duì)象和代理需要實(shí)現(xiàn)同一個(gè)接口,接口中就是被代理的所有方法,代理里面就是對(duì)象要被代理的方法。 因?yàn)橐粋€(gè)對(duì)象覺(jué)得自己身上的功能太多,就會(huì)將一部分功能代理出去,對(duì)象中什么方法想要被代理,在代

    2024年02月11日
    瀏覽(13)
  • Java安全基礎(chǔ)之Java反射機(jī)制和ClassLoader類加載機(jī)制

    Java安全基礎(chǔ)之Java反射機(jī)制和ClassLoader類加載機(jī)制

    目錄 Java 反射機(jī)制 反射 java.lang.Runtime ClassLoader 類加載機(jī)制 URLClassLoader loadClass() 與 Class.forName() 的區(qū)別? Java 反射(Reflection)是 Java 非常重要的動(dòng)態(tài)特性。在運(yùn)行狀態(tài)中,通過(guò) Java 的反射機(jī)制,我們能夠判斷一個(gè)對(duì)象所屬的類。了解任意一個(gè)類的所有屬性和方法。能夠調(diào)用任

    2024年04月22日
    瀏覽(40)
  • Java的反射機(jī)制

    Java 的反射機(jī)制允許在程序運(yùn)行期間,借助反射 API 獲取類的內(nèi)部信息,并能直接操作對(duì)象的內(nèi)部屬性及方法。 Java 反射機(jī)制提供的功能: 在運(yùn)行時(shí),使用反射分析類的能力,獲取有關(guān)類的一切信息(類所在的包、類實(shí)現(xiàn)的接口、標(biāo)注的注解、類的數(shù)據(jù)域、類的構(gòu)造器、類的

    2024年02月02日
    瀏覽(22)
  • Java的反射機(jī)制(2)

    目錄 Class類基本介紹 Class類的常用方法 如何獲取class類對(duì)象 哪些類型有Class對(duì)象 Class類基本介紹 在Java語(yǔ)言中,每個(gè)對(duì)象都有一個(gè)運(yùn)行時(shí)類,即其所屬的類。而這個(gè)運(yùn)行時(shí)類在Java中是以Class類的實(shí)例形式存在的,該Class類實(shí)例就是所謂的Class對(duì)象。Class類表示一個(gè)類或接口的元

    2024年02月08日
    瀏覽(20)
  • Java反射機(jī)制深入詳解

    一.概念 反射就是把Java的各種成分映射成相應(yīng)的Java類。 Class類的構(gòu)造方法是private,由JVM創(chuàng)建。 反射是java語(yǔ)言的一個(gè)特性,它允程序在運(yùn)行時(shí)(注意不是編譯的時(shí)候)來(lái)進(jìn)行自我檢查并且對(duì)內(nèi)部的成員進(jìn)行操作。例如它允許一個(gè)java的類獲取他所有的成員變量和方法并且顯示

    2024年02月06日
    瀏覽(40)
  • Java反射機(jī)制是什么?

    Java反射機(jī)制是什么?

    Java 反射機(jī)制 是 Java 語(yǔ)言的一個(gè)重要特性。 在學(xué)習(xí) Java 反射機(jī)制前,大家應(yīng)該先了解兩個(gè)概念,編譯期和運(yùn)行期。 編譯期 是指把源碼交給編譯器編譯成計(jì)算機(jī)可以執(zhí)行的文件的過(guò)程。在 Java 中也就是把 Java 代碼編成 class 文件的過(guò)程。編譯期只是做了一些翻譯功能,并沒(méi)有把

    2024年02月12日
    瀏覽(11)
  • Java重點(diǎn):反射機(jī)制的使用

    Java重點(diǎn):反射機(jī)制的使用

    目錄 一、概念 二、類類 1、類類的獲取方式 1)類名.Class 2)對(duì)象.getClass() 3)Class.forName() 三、反射實(shí)例化 1、調(diào)用一個(gè)公有的無(wú)參構(gòu)造方法 2、調(diào)用一個(gè)公有的一個(gè)參構(gòu)造方法 3、調(diào)用一個(gè)公有的兩個(gè)參構(gòu)造方法 4、調(diào)用一個(gè)私有的一個(gè)參構(gòu)造方法 四、反射:方法調(diào)用 1、公有

    2024年02月07日
    瀏覽(19)
  • Java學(xué)習(xí)路線(23)——反射機(jī)制

    一、概述 (一)什么是反射: 反射指的是任何一個(gè)Class類,在“運(yùn)行時(shí)”都可以直接得到全部成分。 (二)動(dòng)態(tài)可獲取的對(duì)象: 構(gòu)造器對(duì)象——Constructor,成員變量對(duì)象——Field,成員方法對(duì)象——Method。 (三)反射關(guān)鍵: 第一步都是得到編譯后的Class對(duì)象,然后可以獲得

    2024年02月08日
    瀏覽(15)
  • 【JavaSE】Java的反射機(jī)制

    1.java反射機(jī)制 1.1簡(jiǎn)介 被視為動(dòng)態(tài)語(yǔ)言的關(guān)鍵,允許程序在執(zhí)行期間,借助于RefectionAPI取得任何類的內(nèi)部信息。在程序的運(yùn)行狀態(tài)中,可以構(gòu)造任意一個(gè)類的對(duì)象,可以了解任意一個(gè)類對(duì)象所屬的類,可以了解任意一個(gè)類的成員變量和方法,可以調(diào)用任意一個(gè)對(duì)象的屬性和方

    2024年04月26日
    瀏覽(19)
  • 【Java基礎(chǔ)】深入理解反射、反射的應(yīng)用(工廠模式、代理模式)

    【Java基礎(chǔ)】深入理解反射、反射的應(yīng)用(工廠模式、代理模式)

    Java 反射機(jī)制是指在 運(yùn)行時(shí)動(dòng)態(tài)地獲取和操作類的信息、調(diào)用對(duì)象的方法和訪問(wèn)對(duì)象的屬性的能力 。通過(guò)反射,可以在程序運(yùn)行時(shí)分析和修改類的結(jié)構(gòu)、行為和狀態(tài)。 Java 反射機(jī)制提供了以下功能: 獲取類的信息:可以獲取類的名稱、修飾符、父類、實(shí)現(xiàn)的接口等。 創(chuàng)建對(duì)

    2024年02月09日
    瀏覽(23)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包