反射一些理解

 

java反射詳解html


本身的一些理解:java

反射也能夠理解爲動態調用寫了一個.java文件,編譯後爲字節碼文件,虛擬機加載了這個字節碼文件也就是加載到內存中,就能執行一些指令。在這個類中 當我須要調用另一個類的時候,而內存中並無這個類,這時候我就可使用反射動態加載這個類,使用其中的屬性 跟方法。程序員

class.forName():就是至關於實現了一個IO操做,至關於把我須要的這個類經過IO操做加載到內存中,而後經過instance實例化這個對象,就能夠得到對象的屬性,方法。使用方法時,直接invoke()便可。不實例化對象也能夠得到屬性,方法。框架


Java的反射機制是Java特性之一,反射機制是構建框架技術的基礎所在。靈活掌握Java反射機制,對你們之後學習框架技術有很大的幫助。eclipse

那麼什麼是Java的反射呢?工具

       你們都知道,要讓Java程序可以運行,那麼就得讓Java類要被Java虛擬機加載。Java類若是不被Java虛擬機加載,是不能正常運行的。如今咱們運行的全部的程序都是在編譯期的時候就已經知道了你所須要的那個類的已經被加載了。學習

Java的反射機制是在編譯並不肯定是哪一個類被加載了,而是在程序運行的時候才加載、探知、自審。使用在編譯期並不知道的類。這樣的特色就是反射。spa

 

那麼Java反射有什麼做用呢?.net

假如咱們有兩個程序員,一個程序員在寫程序的時候,須要使用第二個程序員所寫的類,但第二個程序員並沒完成他所寫的類。那麼第一個程序員的代碼可否經過編譯呢?這是不能經過編譯的。利用Java反射的機制,就可讓第一個程序員在沒有獲得第二個程序員所寫的類的時候,來完成自身代碼的編譯。htm

 

Java的反射機制它知道類的基本結構,這種對Java類結構探知的能力,咱們稱爲Java類的「自審」。你們都用過Jcreator和eclipse。當咱們構建出一個對象的時候,去調用該對象的方法和屬性的時候。一按點,編譯工具就會自動的把該對象可以使用的全部的方法和屬性所有都列出來,供用戶進行選擇。這就是利用了Java反射的原理,是對咱們建立對象的探知、自審。

 

Class

       要正確使用Java反射機制就得使用java.lang.Class這個類。它是Java反射機制的起源。當一個類被加載之後,Java虛擬機就會自動產生一個Class對象。經過這個Class對象咱們就能得到加載到虛擬機當中這個Class對象對應的方法、成員以及構造方法的聲明和定義等信息。

 

反射API

u反射API用於反應在當前Java虛擬機中的類、接口或者對象信息

u功能

獲取一個對象的類信息.

  —獲取一個類的訪問修飾符、成員、方法、構造方法以及超類的信息.

  —檢獲屬於一個接口的常量和方法聲明.

  —建立一個直到程序運行期間才知道名字的類的實例.

  —獲取並設置一個對象的成員,甚至這個成員的名字在程序運行期間才知道

  —檢測一個在運行期間才知道名字的對象的方法


使用反射機制的步驟:

u導入java.lang.relfect 

u遵循三個步驟
第一步是得到你想操做的類的 java.lang.Class 對象
第二步是調用諸如 getDeclaredMethods 的方法
第三步使用 反射API 來操做這些信息 

得到Class對象的方法

u若是一個類的實例已經獲得,你可使用

       Class c = 對象名.getClass(); 

      例: TextField t = new TextField();

              Class c = t.getClass();

              Class s = c.getSuperclass();

u若是你在編譯期知道類的名字,你可使用以下的方法

Class c = java.awt.Button.class; 
或者

         Class c = Integer.TYPE;

u若是類名在編譯期不知道可是在運行期能夠得到你可使用下面的方法

          Class c = Class.forName(strg);

package

public class MyTest {

    public static void main(String[] args) {

       TestOne  one=null;

       try{

       Class  cla=Class.forName("com.TestOne");//進行com.TestOne類加載,返回一個Class對象

       System.out.println("********");

       one=(TestOne)cla.newInstance();//產生這個Class類對象的一個實例,調用該類無參的構造方法,做用等同於new TestOne()

       }catch(Exception e){

           e.printStackTrace();

       }

       TestOne two=new TestOne();

  System.out.println(one.getClass() == two.getClass());//比較兩個TestOne對象的Class對象是不是同一個對象,在這裏結果是true。說明若是兩個對象的類型相同,那麼它們會有相同的Class對象

    }

} 

class TestOne{

    static{

       System.out.println("靜態代碼塊運行");

    }

    TestOne(){

       System.out.println("構造方法");

    }

}

靜態代碼塊運行

***********

構造方法

構造方法

 

Class.forName("com.TestOne")的時候,其實是對com.TestOne進行類加載,這時候,會把靜態屬性、方法以及靜態代碼塊都加載到內存中。因此這時候會打印出"靜態代碼塊運行"。但這時候,對象卻尚未產生。因此"構造方法"這幾個字不會打印。當執行cla.newInstance()的時候,就是利用反射機制將Class對象生成一個該類的一個實例。這時候對象就產生了。因此打印"構造方法"。當執行到TestOne two=new TestOne()語句時,又生成了一個對象。但這時候類已經加載完畢,靜態的東西已經加載到內存中,而靜態代碼塊只執行一次,因此不用再去加載類,因此只會打印"構造方法",而"靜態代碼塊運行"不會打印。

相關文章
相關標籤/搜索