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

Java中的反射機(jī)制基本運(yùn)用詳解

 更新時(shí)間:2021年08月31日 10:36:04   作者:劉瑜澄  
這篇文章主要介紹了Java 反射機(jī)制原理與用法,結(jié)合實(shí)例形式詳細(xì)分析了Java反射機(jī)制的相關(guān)概念、原理、基本使用方法及操作注意事項(xiàng),需要的朋友可以參考下

Java中的反射機(jī)制基本運(yùn)用

看完反射可以了解一下注解

注解annotation://www.fzitv.net/article/221276.htm

1、什么是反射(reflect)

反射是java的動(dòng)態(tài)機(jī)制,它允許將對(duì)象的實(shí)例化,方案的調(diào)用,屬性的操作等從編碼期確定轉(zhuǎn)移到程序運(yùn)行期確定。

反射能大大提高代碼的靈活度。但同時(shí)也帶來(lái)了更多的系統(tǒng)開銷和較慢的運(yùn)行效率,因此程序不能過(guò)度依賴反射。

2、反射機(jī)制提供的功能

  • 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類
  • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象(實(shí)例化)
  • 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法
  • 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法——?jiǎng)討B(tài)代理

3、反射->獲取類對(duì)象

在開始之前創(chuàng)建一個(gè)實(shí)體類,用于測(cè)試反射機(jī)制

package reflect_text;
/**
 * 用于測(cè)試反射機(jī)制
 *
 * @author Akio
 * @Create 2021/8/14 10:37
 */
public class Person {
    private String name = "劉瑜澄";//設(shè)置初始值
    private int age = 22;
    public Person() {//無(wú)參構(gòu)造
    }
    public Person(String name, int age) {//有參構(gòu)造
        this.name = name;
        this.age = age;
    }
    public void sayHello() {//無(wú)參方法
        System.out.println(name + ":使用sayHello方法");
    }
    public void sayGoodBye() {//無(wú)參方法
        System.out.println(name + ":使用sayGoodBye方法");
    }
    public void say(String info) {//有參方法
        System.out.println(name + ":" + info);
    }
    public void say(String info, int sum) {//有參方法(重載say方法)
        for (int i = 0; i < sum; i++) {
            System.out.println(name + ":" + info);
        }
    }
    private void privateMethod() {//私有方法
        System.out.println(name + ":這是一個(gè)私有方法");
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

以上這個(gè)用于測(cè)試反射的實(shí)體類創(chuàng)建成功后,先學(xué)習(xí)反射中是如何獲取類對(duì)象的。

反射的第一步就是要獲取操作類的類對(duì)象,即一個(gè)Class的實(shí)例,JVM中每個(gè)被加載的類有且只有一個(gè)類對(duì)象與之對(duì)應(yīng),獲取到這個(gè)類對(duì)象后我們就可以通過(guò)這個(gè)類對(duì)象來(lái)了解該類的一切信息(類名、有哪些方法、屬性等等) 以便在程序運(yùn)行期間通過(guò)反射機(jī)制進(jìn)行相關(guān)操作

這里介紹三種獲取類對(duì)象的方式:

  • (包名.)類名.class
Class personClass = reflect_text.Person.class;
Class intClass = int.class;

這種方式最直接,但是由于是靠硬編碼形式寫死(編譯期間已經(jīng)確定),因此不夠靈活。但是需要注意,基本類型(int\double等)只能通過(guò)這種方式獲取類對(duì)象

  • Class.forName(String className)
Class personClass = Class.forName("reflect_text.Person");
Class stringClass = Class.forName("java.lang.String");

這種方式較為常用,遵循運(yùn)行期綁定。

  • 類加載器ClassLoader
Class stringClass = ClassLoader.getSystemClassLoader().loadClass("java.lang.String");
Class personClass = ClassLoader.getSystemClassLoader().loadClass("reflect_text.Person");

在這一節(jié)中介紹幾個(gè)簡(jiǎn)單的方法:

getName()
獲取類的完全限定名:包名.類名
getSimpleName()
僅僅獲取類名
getMethods()
返回一個(gè)Method數(shù)組,獲取class所表示的類的所有公開方法(包含從超類中繼承的方法)

例子:

		Scanner scanner = new Scanner(System.in);
		Class cls = Class.forName(scanner.nextLine());//運(yùn)行期綁定
        String name = cls.getName();//獲取類的完全限定名:包名.類名
        System.out.println("完全限定名 = " + name);
        name = cls.getSimpleName();//僅獲取類名
        System.out.println("僅類名 = " + name);
        Method[] methods = cls.getMethods();
        for (Method m : methods) {
            System.out.print(m.getName()+"\t");
        }

4、反射->利用無(wú)參構(gòu)造實(shí)例化對(duì)象

Class類中提供了一個(gè)方法newInstance()來(lái)實(shí)例化,該方法要求此類必須具有無(wú)參構(gòu)造器,它是通過(guò)無(wú)參構(gòu)造器實(shí)例化對(duì)象的。

		Person person = new Person();
        //1獲取要實(shí)例化的類的類對(duì)象
        Scanner scanner = new Scanner(System.in);
        System.out.println("請(qǐng)輸入類名:");
        Class cls = Class.forName(scanner.nextLine());
        /*
            通過(guò)Class提供的方法newInstance()來(lái)實(shí)例化
           	該方法要求此類必須具有無(wú)參構(gòu)造器,它是通過(guò)無(wú)參構(gòu)造器實(shí)例化對(duì)象的
         */
        Object obj = cls.newInstance();
        System.out.println("obj = " + obj);

在這里插入圖片描述

5、反射->利用有參構(gòu)造實(shí)例化對(duì)象

getConstructor()
//獲取無(wú)參構(gòu)造器,可以利用無(wú)參構(gòu)造器實(shí)例化對(duì)象,但這個(gè)方法對(duì)于使用無(wú)參構(gòu)造器實(shí)例化對(duì)象可有可無(wú)
getConstructor(類對(duì)象)
//通過(guò)類對(duì)象獲取特定的構(gòu)造器,該參數(shù)列表是根據(jù)特定構(gòu)造器的參數(shù)列表類型來(lái)決定的,如
		getConstructor(String.class, int.class)
		即為調(diào)用Person類中兩個(gè)參數(shù)的有參構(gòu)造器
		public Person(String name, int age) {//有參構(gòu)造
    		this.name = name;
    		this.age = age;
		}

舉例

		//加載類對(duì)象
        Class cls = Class.forName("reflect.Person");
        //通過(guò)類對(duì)象獲取特定的構(gòu)造器
        Constructor c = cls.getConstructor(String.class, int.class);
        Object o = c.newInstance("流年", 21);//實(shí)例化
        System.out.println(o);

結(jié)果可知初始值已經(jīng)被修改

在這里插入圖片描述

6、反射->調(diào)用無(wú)參方法

getMethod(String MethodName)
獲取類對(duì)象的MethodName方法,返回值類型為Method
invoke(Object object)
執(zhí)行object對(duì)象的某方法

舉例

		//一般調(diào)用方法的做法-------------------
        Person p = new Person();//實(shí)例化對(duì)象
        p.sayHello();//調(diào)用該對(duì)象方法
        //反射機(jī)制調(diào)用方法-----------------------
        //1、實(shí)例化對(duì)象
        Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        //2、調(diào)用o的sayHello方案
        //2.1通過(guò)Class獲取Person的sayHello方法
        Method method = cls.getMethod("sayHello");
        //2.2調(diào)用o的該方法
        method.invoke(o);//等效于一般方法中的o.sayHello()

可見兩種操作均能達(dá)到一樣的效果

在這里插入圖片描述

7、反射->調(diào)用有參方法

getMethod(String MethodName, 類對(duì)象)
獲取類對(duì)象的MethodName有參方法,并傳入對(duì)應(yīng)參數(shù)類型的類對(duì)象,返回值類型為Method

舉例

		//一般調(diào)用有參方法------------------------
        Person p = new Person();
        p.say("七夕快樂(lè)~");
        p.say("七夕快樂(lè)~",3);
        //反射機(jī)制調(diào)用有參方法---------------------
        Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        //調(diào)用say(String info)方法
        Method m1 = cls.getMethod("say", String.class);
        m1.invoke(o, "春節(jié)快樂(lè)~");
        //調(diào)用say(String info, int sum)
        Method m2 = cls.getMethod("say", String.class, int.class);
        m2.invoke(o,"春節(jié)快樂(lè)~",3);

通過(guò)結(jié)果可以看到,效果都是一樣的

在這里插入圖片描述

8、反射->訪問(wèn)私有方法

注意:反射訪問(wèn)私有的方法,但是會(huì)破壞類的封裝性

getDeclaredMethod(String MethodName)
可以僅獲取此類定義的所有方法,包含私有方法
setAccessible(boolean flag)
開啟私有方法的訪問(wèn)權(quán)限

舉例

		//正常情況下,在本類中不可以訪問(wèn)外部的私有方法
		//但在反射機(jī)制中可行
		Class cls = Class.forName("reflect_text.Person");
        Object o = cls.newInstance();
        Method method = cls.getDeclaredMethod("privateMethod");
        method.setAccessible(true);//打開訪問(wèn)權(quán)限
        method.invoke(o);

在這里插入圖片描述

9、反射->類加載路徑

加載資源時(shí)常用相對(duì)路徑,之前學(xué)習(xí)的相對(duì)路徑./由于運(yùn)行環(huán)境不同,位置并非固定,因此實(shí)際開發(fā)中使用較少。
接下來(lái)介紹,在開發(fā)中常用的類加載路徑

常用的路徑通常為類的加載路徑,有兩個(gè):

1:類對(duì)象.getResource()與當(dāng)前類所處同一目錄

2:類加載器.getResource()類加載路徑,類的package定義中根包位置。

例如:有一個(gè)類:
package reflect_text;
public class WebServer{
     ……
}
在WebServer類中,當(dāng)我們使用上述兩種方式獲取路徑時(shí)他們的對(duì)應(yīng)位置為:
WebServer.class.getResource()
當(dāng)前WebServer所在的目錄(編譯后的class文件所在目錄)
WebServer.class.getClassLoader().getResource()
則是在WebServer的包的最上級(jí),即com包的上一級(jí)
package reflect_text;
public class ReflectDemo {
		File dir = new File(ReflectDemo.class.getResource(".").toURI());
        System.out.println("dir = " + dir);
        //dir = D:\ClassCode\JavaSE_API\out\production\JavaSE_API\reflect
        File dir2 = new File(ReflectDemo.class.getClassLoader().getResource(".").toURI());
        System.out.println("dir2 = " + dir2);
        //dir2 = D:\ClassCode\JavaSE_API\out\production\JavaSE_API
}

在這里插入圖片描述

總結(jié)

本片文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • mybatis?like模糊查詢特殊字符報(bào)錯(cuò)轉(zhuǎn)義處理方式

    mybatis?like模糊查詢特殊字符報(bào)錯(cuò)轉(zhuǎn)義處理方式

    這篇文章主要介紹了mybatis?like模糊查詢特殊字符報(bào)錯(cuò)轉(zhuǎn)義處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java list 比較詳解及實(shí)例

    java list 比較詳解及實(shí)例

    這篇文章主要介紹了java list 比較詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Spring MVC--攔截器實(shí)現(xiàn)和用戶登陸例子

    Spring MVC--攔截器實(shí)現(xiàn)和用戶登陸例子

    本文主要介紹了Spring MVC--攔截器實(shí)現(xiàn)和用戶登陸例子,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-03-03
  • MyBatis圖文并茂講解注解開發(fā)一對(duì)多查詢

    MyBatis圖文并茂講解注解開發(fā)一對(duì)多查詢

    這篇文章主要介紹了SpringBoot中Mybatis注解一對(duì)多查詢的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Spring體系的各種啟動(dòng)流程詳解

    Spring體系的各種啟動(dòng)流程詳解

    這篇文章主要給大家介紹了關(guān)于Spring體系的各種啟動(dòng)流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • java多線程Thread的實(shí)現(xiàn)方法代碼詳解

    java多線程Thread的實(shí)現(xiàn)方法代碼詳解

    這篇文章主要介紹了java多線程Thread的實(shí)現(xiàn)方法代碼詳解,涉及start(),run(),stop(),interrupt(),isInterrupted(),join()和join(long millis)等方法的介紹,具有一定借鑒價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 項(xiàng)目管理利器-Maven(Windows安裝)圖文教程

    項(xiàng)目管理利器-Maven(Windows安裝)圖文教程

    下面小編就為大家?guī)?lái)一篇項(xiàng)目管理利器-Maven(Windows安裝)圖文教程。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Java批量插入數(shù)據(jù)的代碼實(shí)現(xiàn)

    Java批量插入數(shù)據(jù)的代碼實(shí)現(xiàn)

    日常工作或者學(xué)習(xí)中,可能會(huì)遇到批量插入數(shù)據(jù)的需求,一般情況下數(shù)據(jù)量少的時(shí)候,我們會(huì)直接調(diào)用批量接口插入數(shù)據(jù)即可,當(dāng)數(shù)據(jù)量特別大時(shí),我們就會(huì)用到分批插入數(shù)據(jù),所以本文給大家介紹了Java批量插入數(shù)據(jù)的代碼實(shí)現(xiàn),需要的朋友可以參考下
    2024-01-01
  • Spring Boot(二)之web綜合開發(fā)

    Spring Boot(二)之web綜合開發(fā)

    本篇文章為大家介紹spring boot的其它特性(有些未必是spring boot體系桟的功能,但是是spring特別推薦的一些開源技術(shù)本文也會(huì)介紹),對(duì)了這里只是一個(gè)大概的介紹,特別詳細(xì)的使用我們會(huì)在其它的文章中來(lái)展開說(shuō)明
    2017-05-05
  • Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)

    Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)

    FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計(jì)算機(jī)程序,本文主要介紹了Java工程使用ffmpeg進(jìn)行音視頻格式轉(zhuǎn)換的實(shí)現(xiàn)
    2024-02-02

最新評(píng)論

康马县| 永善县| 沈阳市| 剑河县| 高尔夫| 兰州市| 离岛区| 米泉市| 法库县| 依兰县| 昌黎县| 威信县| 武夷山市| 通海县| 新邵县| 武穴市| 海盐县| 任丘市| 瓮安县| 上饶县| 翼城县| 永川市| 赤峰市| 来凤县| 杭锦旗| 封丘县| 合肥市| 安西县| 淅川县| 靖远县| 遂宁市| 晋城| 德州市| 河北省| 句容市| SHOW| 巴塘县| 本溪| 浦城县| 甘泉县| 桃园县|