欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的反射機(jī)制示例詳解

 更新時(shí)間:2022年03月09日 15:25:05   作者:不想起床的小張  
反射就是把Java類(lèi)中的各個(gè)成分映射成一個(gè)個(gè)的Java對(duì)象。本文將通過(guò)示例詳細(xì)講解Java中的反射機(jī)制,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下

反射

反射就是把Java類(lèi)中的各個(gè)成分映射成一個(gè)個(gè)的Java對(duì)象。即在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所以屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能調(diào)用它的任意一個(gè)方法和屬性。這種動(dòng)態(tài)獲取信息及動(dòng)態(tài)調(diào)用對(duì)象方法的功能叫Java的反射機(jī)制

每一個(gè)Java程序執(zhí)行必須通過(guò)編譯、加載、鏈接和初始化四個(gè)階段

1.編譯:將.java.文件編譯成字節(jié)碼.class文件

2.加載:查找并加載類(lèi)的二進(jìn)制數(shù)據(jù)

3.鏈接:

  • 驗(yàn)證:確保被加載類(lèi)的正確性
  • 為類(lèi)的靜態(tài)變量分配內(nèi)存,并將其初始化為默認(rèn)值
  • 將類(lèi)中的符號(hào)轉(zhuǎn)換為直接引用

4.初始化:為類(lèi)的靜態(tài)變量賦予正確的初始值

什么是Class類(lèi)

在Java中,每個(gè)class都有一個(gè)相應(yīng)的Class對(duì)象。也就是說(shuō),當(dāng)我們編寫(xiě)一個(gè)類(lèi),編譯完成后,在生成的.class文件中,就會(huì)產(chǎn)生一個(gè)Class對(duì)象,用于表示這個(gè)類(lèi)的類(lèi)型信息

也就是說(shuō),無(wú)論你是什么對(duì)象,總會(huì)有有一個(gè)隱藏的Class對(duì)象與你相對(duì)應(yīng),而Class的實(shí)例表示正在運(yùn)行的 Java 應(yīng)用程序中的類(lèi)和接口。借此,實(shí)現(xiàn)了我們Java的反射機(jī)制。

獲取Class實(shí)例的三種方式

實(shí)例化對(duì)象調(diào)用getClass()方法

使用Class類(lèi)的靜態(tài)方法forName(),用類(lèi)的名字獲取一個(gè)Class實(shí)例

運(yùn)用.class的方式來(lái)獲取Class實(shí)例,對(duì)于基本數(shù)據(jù)類(lèi)型的封裝類(lèi),還可以采用.TYPE來(lái)獲取相對(duì)應(yīng)的基本數(shù)據(jù)類(lèi)型的Class實(shí)例

用代碼來(lái)看一看:

public class reflect {

    public static void main(String[] args) throws ClassNotFoundException {

        Apple apple = new Apple();

        // 使用對(duì)象的getClass()方法
        Class a1 = apple.getClass();

        // 使用Class類(lèi)的靜態(tài)方法forName()
        Class a2 = Class.forName("p1.apple");

        // 運(yùn)用.class的方式來(lái)獲取Class實(shí)例
        Class a3 = Apple.class;

        System.out.printf("a1: %s\na2: %s\na3: %s", a1, a2, a3);

    }

}

class Apple {

    private Integer weight;

    private String color;
    
}

打印結(jié)果:

a1: class p1.apple
a2: class p1.apple
a3: class p1.apple
進(jìn)程已結(jié)束,退出代碼0

通過(guò)反射創(chuàng)建類(lèi)對(duì)象

通過(guò)反射創(chuàng)建類(lèi)對(duì)象主要有兩種方式:通過(guò) Class 對(duì)象的 newInstance() 方法、通過(guò) Constructor 對(duì)象的 newInstance() 方法。

public class reflect {

    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {

        // 通過(guò) Class 對(duì)象的 newInstance() 方法
        Class temp1 = Apple.class;
        Apple apple1 = (Apple) temp1.newInstance();
        
        // 通過(guò) Constructor 對(duì)象的 newInstance() 方法
        Class temp2 = Apple.class;
        Constructor constructor1 = temp2.getConstructor();
        Apple apple2 = (Apple)constructor1.newInstance();

        // 通過(guò) Constructor 對(duì)象創(chuàng)建類(lèi)對(duì)象可以選擇特定構(gòu)造方法,而通過(guò) Class 對(duì)象則只能使用默認(rèn)的無(wú)參數(shù)構(gòu)造方法。
        Class temp3 = Apple.class;
        Constructor constructor2 = temp3.getConstructor(Integer.class,String.class);
        Apple apple = (Apple)constructor2.newInstance(2, "Red");
        System.out.println(apple);

    }

}

class Apple {

    private Integer weight;

    private String color;

    // 無(wú)參構(gòu)造器
    public Apple() {
        System.out.println("我是無(wú)參構(gòu)造!");
    }

    // 有參構(gòu)造器
    public Apple(Integer weight,String color) {
        this.weight = weight;
        this.color = color;
    }

    // 重寫(xiě)方法 方便打印顯示對(duì)象內(nèi)容
    @Override
    public String toString() {
        return "Apple{" +
                "weight=" + weight +
                ", color='" + color + '\'' +
                '}';
    }

}

打印結(jié)果:

我是無(wú)參構(gòu)造!
我是無(wú)參構(gòu)造!
Apple{weight=2, color='Red'}

進(jìn)程已結(jié)束,退出代碼0

通過(guò)反射獲取類(lèi)屬性、方法、構(gòu)造器

public class reflect {

    public static void main(String[] args) throws NoSuchFieldException {

        // 返回一個(gè)類(lèi)中所有可訪(fǎng)問(wèn)的公共字段,包括該類(lèi)的公共字段和其繼承的類(lèi)的公共字段
        Field[] fields1 = Apple.class.getFields();
        System.out.println("getFields結(jié)果");
        Arrays.stream(fields1).forEach(System.out::println);

        // 返回一個(gè)類(lèi)中全部字段,但只包括該類(lèi)的字段
        Field[] fields2 = Apple.class.getDeclaredFields();
        System.out.println("getDeclaredFields結(jié)果");
        Arrays.stream(fields2).forEach(System.out::println);

        // 根據(jù)字段名返回一個(gè)公開(kāi)字段
        Field field1 = Apple.class.getField("noThing");
        System.out.println("getField結(jié)果");
        System.out.println(field1);

        // 根據(jù)字段名返回一個(gè)字段
        Field field2 = Apple.class.getDeclaredField("color");
        System.out.println("getDeclaredField結(jié)果");
        System.out.println(field2);

        // 同F(xiàn)ield Method也有四種獲取方式
        // 這里舉其中一個(gè)例子
        Method[] methods = Apple.class.getDeclaredMethods();
        System.out.println("getDeclaredMethods結(jié)果");
        Arrays.stream(methods).forEach(System.out::println);

        // 同上 舉一個(gè)獲取構(gòu)造器的例子
        Constructor[] constructors = Apple.class.getDeclaredConstructors();
        System.out.println("getDeclaredConstructors結(jié)果");
        Arrays.stream(constructors).forEach(System.out::println);

    }

}

class Apple {

    private Integer weight;

    private String color;

    public String noThing;

    public Apple() {

    }

    public Apple(Integer weight, String color) {
        this.weight = weight;
        this.color = color;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "weight=" + weight +
                ", color='" + color + '\'' +
                '}';
    }

}

打印結(jié)果:

getFields結(jié)果
public java.lang.String p1.Apple.noThing
getDeclaredFields結(jié)果
private java.lang.Integer p1.Apple.weight
private java.lang.String p1.Apple.color
public java.lang.String p1.Apple.noThing
getField結(jié)果
public java.lang.String p1.Apple.noThing
getDeclaredField結(jié)果
private java.lang.String p1.Apple.color
getDeclaredMethods結(jié)果
public java.lang.String p1.Apple.toString()
getDeclaredConstructors結(jié)果
public p1.Apple()
public p1.Apple(java.lang.Integer,java.lang.String)

更改訪(fǎng)問(wèn)權(quán)限和實(shí)例賦值

首先,通過(guò)field.setAccessible()可更改屬性的訪(fǎng)問(wèn)權(quán)限

public class reflect {

    public static void main(String[] args) throws NoSuchFieldException {

        // 實(shí)例化一個(gè)Apple
        Apple apple = new Apple();

        // 獲取所有字段 并統(tǒng)一設(shè)定為公有屬性
        Field[] fields = Apple.class.getDeclaredFields();
        Arrays.stream(fields).forEach( field -> {
            field.setAccessible(true);
            // 打印結(jié)果
            System.out.println(field);
            try {
                if (field.getType() == Integer.class) {
                    field.set(apple, 5);
                } else if (field.getType() == String.class) {
                    field.set(apple, "Red");
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        });
        // 查看apple結(jié)果
        System.out.println(apple);
      
    }

}

class Apple {

    private Integer weight;

    private String color;

    @Override
    public String toString() {
        return "Apple{" +
                "weight=" + weight +
                ", color='" + color + '\'' +
                '}';
    }

}

打印結(jié)果:

private java.lang.Integer p1.Apple.weight
private java.lang.String p1.Apple.color
Apple{weight=5, color='Red'}

進(jìn)程已結(jié)束,退出代碼0

通過(guò)源碼文檔和打印結(jié)果,可見(jiàn)setAccessable()方法并沒(méi)有改變類(lèi)字段的訪(fǎng)問(wèn)權(quán)限,而是作為一個(gè)標(biāo)志,使得我們反射獲取實(shí)例過(guò)程中可以對(duì)其進(jìn)行操作

運(yùn)用場(chǎng)景

在我看來(lái),反射機(jī)制實(shí)際上就是上帝模式,如果說(shuō)方法的調(diào)用是 Java 正確的打開(kāi)方式,那反射機(jī)制就是上帝偷偷開(kāi)的后門(mén),只要存在對(duì)應(yīng)的class,一切都能夠被調(diào)用。

眾所周知,語(yǔ)言有靜態(tài)語(yǔ)言和動(dòng)態(tài)語(yǔ)言?xún)纱蠓诸?lèi),靜態(tài)語(yǔ)言例如C/C++、Java、C#等,動(dòng)態(tài)語(yǔ)言有Python、PHP、JavaScript等。為了讓Java語(yǔ)言也有動(dòng)態(tài)語(yǔ)言的特性,有了反射機(jī)制,解耦以及提高代碼的靈活性。

反射在開(kāi)發(fā)過(guò)中或許并不常見(jiàn),可我們使用的框架工具底層都有反射的存在。動(dòng)態(tài)代理設(shè)計(jì)模式、JDBC 的數(shù)據(jù)庫(kù)的連接、Spring 框架的使用等都應(yīng)用到了反射機(jī)制。

以上就是Java中的反射機(jī)制示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Java反射機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java定時(shí)任務(wù)的三種實(shí)現(xiàn)方式

    Java定時(shí)任務(wù)的三種實(shí)現(xiàn)方式

    這篇文章主要給大家介紹了關(guān)于Java定時(shí)任務(wù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼

    Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼

    這篇文章主要介紹了Spring Boot 實(shí)現(xiàn)Restful webservice服務(wù)端示例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-11-11
  • 新手小白看過(guò)來(lái)學(xué)JAVA必過(guò)IO流File字節(jié)流字符流

    新手小白看過(guò)來(lái)學(xué)JAVA必過(guò)IO流File字節(jié)流字符流

    這篇文章主要介紹了新手小白學(xué)JAVA到IO流File字節(jié)流字符流的重點(diǎn),對(duì)流不清楚的新手同學(xué)快進(jìn)來(lái)學(xué)習(xí)吧,大佬也可以進(jìn)來(lái)溫故一下
    2021-08-08
  • Java序列化常見(jiàn)實(shí)現(xiàn)方法代碼實(shí)例

    Java序列化常見(jiàn)實(shí)現(xiàn)方法代碼實(shí)例

    這篇文章主要介紹了Java序列化常見(jiàn)實(shí)現(xiàn)方法代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • Java 多線(xiàn)程傳值的四種方法

    Java 多線(xiàn)程傳值的四種方法

    這篇文章主要介紹了Java 多線(xiàn)程傳值的四種方法,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下
    2020-09-09
  • Java如何把數(shù)組轉(zhuǎn)換為ArrayList

    Java如何把數(shù)組轉(zhuǎn)換為ArrayList

    這篇文章主要介紹了Java如何把數(shù)組轉(zhuǎn)換為ArrayList,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Tk.mybatis零sql語(yǔ)句實(shí)現(xiàn)動(dòng)態(tài)sql查詢(xún)的方法(4種)

    Tk.mybatis零sql語(yǔ)句實(shí)現(xiàn)動(dòng)態(tài)sql查詢(xún)的方法(4種)

    有時(shí)候,查詢(xún)數(shù)據(jù)需要根據(jù)條件使用動(dòng)態(tài)查詢(xún),這時(shí)候需要使用動(dòng)態(tài)sql,本文主要介紹了Tk.mybatis零sql語(yǔ)句實(shí)現(xiàn)動(dòng)態(tài)sql查詢(xún)的方法,感興趣的可以了解一下
    2021-12-12
  • Java文檔注釋用法+JavaDoc的使用說(shuō)明

    Java文檔注釋用法+JavaDoc的使用說(shuō)明

    這篇文章主要介紹了Java文檔注釋用法+JavaDoc的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 淺析JAVA中的內(nèi)存結(jié)構(gòu)、重載、this與繼承

    淺析JAVA中的內(nèi)存結(jié)構(gòu)、重載、this與繼承

    這篇文章主要介紹了 JAVA中的內(nèi)存結(jié)構(gòu)、重載、this與繼承的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • Java 反射機(jī)制

    Java 反射機(jī)制

    這篇文章簡(jiǎn)要的說(shuō)明了Java的反射機(jī)制,Java的反射是框架設(shè)計(jì)的靈魂,本文通過(guò)例子能看的更加清晰的理解
    2021-06-06

最新評(píng)論