日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java反射重要么_JAVA反射----这些知识你需要知道

發(fā)布時(shí)間:2024/9/19 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java反射重要么_JAVA反射----这些知识你需要知道 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言:

在學(xué)習(xí)JAVA的反射之前我覺得很有必要花幾分鐘時(shí)間了解一下JVM的內(nèi)存結(jié)構(gòu)。如果一開始就說什么是反射,以及反射的API。這樣做是很難真正的理解反射的。

JVM是JAVA跨平臺(tái)的核心,其結(jié)構(gòu)為上圖所示。我們注意到其運(yùn)行時(shí)數(shù)據(jù)區(qū)也就是我們常說的內(nèi)存結(jié)構(gòu)包括堆區(qū),方法區(qū),棧區(qū)等。那么我們JAVA程序在運(yùn)行的時(shí)候,運(yùn)行時(shí)數(shù)據(jù)區(qū)每個(gè)區(qū)域存儲(chǔ)的哪些數(shù)據(jù)呢。

程序計(jì)數(shù)器:簡(jiǎn)單將程序計(jì)數(shù)器就是用來指示需要執(zhí)行哪條指令。由此看出它是線程私有的,因?yàn)槲覀冎蓝嗑€程的本質(zhì)是線程搶占CPU時(shí)間片的過程,所以我們線程中指令不斷的終止和運(yùn)行,所以要回到運(yùn)行狀態(tài)必須要程序計(jì)數(shù)器記錄下應(yīng)該執(zhí)行的指令編號(hào)。(因?yàn)槊刻熘噶畹拇笮∈枪潭ǖ乃圆粫?huì)存在內(nèi)存泄漏的情況)

JAVA棧:JAVA棧也稱為JAVA執(zhí)行方法的內(nèi)存模型,存儲(chǔ)了方法中聲明的局部變量包括聲明的局部變量形參,運(yùn)行時(shí)常量池引用以及返回地址。JAVA的運(yùn)行其實(shí)就是一個(gè)方法棧幀的壓棧與彈棧的過程。

堆區(qū):Java中的堆是用來存儲(chǔ)對(duì)象本身的以及數(shù)組(當(dāng)然,數(shù)組引用是存放在Java棧中的)。只不過和C語言中的不同,在Java中,程序員基本不用去關(guān)心空間釋放的問題,Java的垃圾回收機(jī)制會(huì)自動(dòng)進(jìn)行處理。因此這部分空間也是Java垃圾收集器管理的主要區(qū)域。另外,堆是被所有線程共享的,在JVM中只有一個(gè)堆。

方法區(qū):方法區(qū)在JVM中也是一個(gè)非常重要的區(qū)域,它與堆一樣,是被線程共享的區(qū)域。在方法區(qū)中,存儲(chǔ)了每個(gè)類的信息(包括類的名稱、方法信息、字段信息)、靜態(tài)變量、常量以及編譯器編譯后的代碼等。在Class文件中除了類的字段、方法、接口等描述信息外,還有一項(xiàng)信息是常量池,用來存儲(chǔ)編譯期間生成的字面量和符號(hào)引用。在方法區(qū)中有一個(gè)非常重要的部分就是運(yùn)行時(shí)常量池,它是每一個(gè)類或接口的常量池的運(yùn)行時(shí)表示形式,在類和接口被加載到JVM后,對(duì)應(yīng)的運(yùn)行時(shí)常量池就被創(chuàng)建出來。當(dāng)然并非Class文件常量池中的內(nèi)容才能進(jìn)入運(yùn)行時(shí)常量池,在運(yùn)行期間也可將新的常量放入運(yùn)行時(shí)常量池中,比如String的intern方法。

類加載的過程其實(shí)就是JVM將外部的靜態(tài)class字節(jié)碼加載到JVM方法區(qū)形成動(dòng)態(tài)數(shù)據(jù)并在堆中形成一個(gè)java.lang.Class對(duì)象。這個(gè)對(duì)象相當(dāng)于一面鏡子與方法區(qū)中真正對(duì)象對(duì)應(yīng),這個(gè)Class對(duì)象就是反射的核心。

了解Class

既然Class對(duì)象是反射的核心,那么什么是Class呢?我們來看一下JDK7中是怎么定義的:

* Instances of the class{@code Class} represent classes and* interfaces in a running Java application. An enumis a kind of* class and an annotation is a kind of interface. Every array also* belongs to a classthat is reflected as a {@code Class} object*that is shared by all arrays with the same element type and number* of dimensions. The primitive Java types ({@code boolean},* {@code byte}, {@code char}, {@code short},* {@code int}, {@code long}, {@code float}, and* {@code double}), and the keyword {@code void} are also*represented as {@code Class} objects.*

*

{@code Class} has no publicconstructor. Instead {@code Class}*objects are constructed automatically by the Java Virtual Machine as classes* are loaded and by calls to the {@code defineClass} method in the class

* loader.

大概意思為:Class的實(shí)例代表正在運(yùn)行JAVA程序中的對(duì)象和接口。枚舉類型是一種對(duì)象而注解是一種接口。每個(gè)數(shù)組是被映射為Class的一個(gè)類,而具有相同數(shù)據(jù)類型和維數(shù)的數(shù)組都共享該Class類。基本數(shù)據(jù)類型依然是Class對(duì)象。Class沒有公共的構(gòu)造方法。所有的Class對(duì)象都是在JVM被加載的時(shí)候自動(dòng)調(diào)用defineClass創(chuàng)建。

反射作用

可以通過反射得到類成員變量,成員方法以及構(gòu)造方法并可以操作他們,即使是私有的也可以訪問并操作。

提高代碼靈活性

反射示例

首先創(chuàng)建一個(gè)測(cè)試Student類:

public classStudent {private intage;privateString name;private double score; //三個(gè)私有屬性

public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}publicString getName() {returnname;

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

}public doublegetScore() {returnscore;

}public void setScore(doublescore) {this.score =score;

}public Student(){//公共不帶參構(gòu)造

}private Student(int age,String name,double score){//私有帶參構(gòu)造

this.age =age;this.name =name;this.score =score;

}

}

三種方式獲取Class對(duì)象:

Class clazz1 = Class.forName("reflection.Student");

Class clazz2= Student.class;

Student student= newStudent();

Class clazz3=student.getClass();

System.out.println(clazz1==clazz2);

System.out.println(clazz1==clazz3);

輸出結(jié)果為:ture/ture 根據(jù)傳遞性可知這三個(gè)對(duì)象是同一個(gè)

2.通過反射得到實(shí)例對(duì)象

Class clazz1 = Class.forName("reflection.Student");

Object obj= clazz1.newInstance();//調(diào)用了無參構(gòu)造函數(shù)

3.通過反射得到類私有變量并賦值

Class clazz1 = Class.forName("reflection.Student");

Object o=clazz1.newInstance();

Field files1= clazz1.getDeclaredField("age");

files1.setAccessible(true); //打破私有訪問屬性

files1.set(o, 12);

System.out.println(files1.get(o));

4.通過反射執(zhí)行私有構(gòu)造函數(shù)

Constructor a = clazz1.getDeclaredConstructor(int.class,String.class,double.class);

a.setAccessible(true);

Student stu= (Student)a.newInstance(12,"李強(qiáng)",12);

System.out.println("學(xué)生信息獲取到:"+stu.getName());

5.通過反射執(zhí)行成員方法

Constructor a = clazz1.getDeclaredConstructor(int.class,String.class,double.class);

a.setAccessible(true);

Student stu= (Student)a.newInstance(12,"李強(qiáng)",12);

System.out.println("學(xué)生信息獲取到:"+stu.getName());

Method method= clazz1.getMethod("setName", String.class);

method.invoke(stu,"芳芳");

System.out.println("學(xué)生信息獲取到:"+stu.getName());

總結(jié)

以上是生活随笔為你收集整理的java反射重要么_JAVA反射----这些知识你需要知道的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。