久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > java學習中(zhong)如何認識反射,業內專家告(gao)訴你

java學習中如(ru)何認識反(fan)射,業內專家告訴你 時間:2018-06-22      來(lai)源:未知

反射的概念

反射的概(gai)念(nian)是由(you) Smith 在(zai)1982年首(shou)次提出的,主要是指程序可(ke)以訪問(wen)、檢(jian)測和修(xiu)改(gai)它(ta)本身狀態或行為的一種能力。

換句話說,就是能夠得到(dao)代(dai)碼(ma)自(zi)身的特征。

換句(ju)話說,就(jiu)是(shi)把類(lei)(lei)本身也(ye)看成是(shi)對象,包(bao)括類(lei)(lei)中的(de)變量名、方(fang)法名、內部類(lei)(lei)、超類(lei)(lei)、包(bao)、修飾符(fu)等(deng)等(deng),都可以(yi)通過代碼(ma)來(lai)得到并被(bei)看成是(shi)對象。

java為此設計了(le)一些類來方(fang)便我們使用反射。這些類并不多,它們分別是:Field、Constructor、Method、Class、Object,下面對(dui)這些類做一個(ge)簡(jian)單的說(shuo)明。

摘抄于其它(ta)資料,僅供閱讀

Field 類:提供有關類或(huo)接口的(de)屬性的(de)信息(xi),以及對它的(de)動(dong)態訪問(wen)權限。反射的(de)字段可能是一個類(靜態)屬性或(huo)實(shi)例屬性,簡單(dan)的(de)理解可以把它看成(cheng)一個封裝反射類的(de)屬性的(de)類。

Constructor 類:提供關于(yu)類的(de)單個(ge)構造(zao)方法(fa)的(de)信息以及(ji)對它(ta)的(de)訪(fang)問(wen)權限。這個(ge)類和 Field 類不(bu)同,Field 類封(feng)裝了反射類的(de)屬性,而 Constructor 類則封(feng)裝了反射類的(de)構造(zao)方法(fa)。

Method 類:提供(gong)關(guan)于類或(huo)接(jie)口上某個單獨方法(fa)(fa)(fa)的(de)信息。所反映的(de)方法(fa)(fa)(fa)可能是類方法(fa)(fa)(fa)或(huo)實例方法(fa)(fa)(fa)(包括抽象方法(fa)(fa)(fa))。 這(zhe)個類不難理解(jie),它是用(yong)來封裝反射類方法(fa)(fa)(fa)的(de)一個類。

Class 類:類的(de)(de)實例表示(shi)正在(zai)運行的(de)(de) Java 應(ying)用程序中的(de)(de)類和接口。枚舉是一種類,注釋(shi)是一種接口。每個數(shu)組(zu)屬于被映射為 Class 對(dui)(dui)象的(de)(de)一個類,所有(you)具有(you)相同元素類型和維數(shu)的(de)(de)數(shu)組(zu)都共(gong)享該(gai) Class 對(dui)(dui)象。

Object 類:每個類都(dou)使用 Object 作為超類。所有對象(包括數組)都(dou)實現這個類的方法。

獲取Class類(lei)

有(you)一個(ge)(ge)類(lei),類(lei)名是(shi)Class,(首字母大寫,不同于關鍵字class)。任何一個(ge)(ge)java類(lei)都是(shi)這個(ge)(ge)Class類(lei)的(de)對(dui)象(xiang),即“類(lei)本身也是(shi)對(dui)象(xiang)”的(de)感覺(jue)。

一(yi)旦我們(men)獲(huo)取到了一(yi)個類(lei)(lei)的(de)Class實例,那么在此(ci)基礎(chu)上要獲(huo)取Field、Constructor、Method等(deng)等(deng)的(de)話也就很容易了(因(yin)此(ci)java的(de)所有代碼都在類(lei)(lei)中的(de)嘛)。所以(yi)首要步驟是獲(huo)取Class實例。

獲(huo)取(qu)類自身(shen)有三種方式(shi):

(1)利(li)用 對(dui)象.getClass() 的方式(shi)獲取該對(dui)象的Class實例;

(2)利用 對象.class 的方式(shi)來獲(huo)取(qu)Class實例,對于基本數據(ju)類(lei)型的封裝類(lei),還可以采用.TYPE來獲(huo)取(qu)相對應的基本數據(ju)類(lei)型的Class實例;

(3)使用(yong) Class類的靜(jing)態(tai)方法forName(“全路徑名”),用(yong)類的名字獲取一個(ge)Class實例(li)。

示例

class ClassTest {

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

String str1 = "abc";

Class cls1 = str1.getClass();//法一

Class cls2 = String.class;//法二

Class cls3 = Class.forName("java.lang.String");//法(fa)三

System.out.println(cls1 == cls2);

System.out.println(cls1 == cls3);

}

}

運行結果為

true

true

解釋

1、運行(xing)結果(guo)為true說明虛擬機為某個(ge)(ge)類只會產生一份字(zi)節(jie)(jie)碼,將來用這(zhe)份字(zi)節(jie)(jie)碼可(ke)以產生多(duo)個(ge)(ge)實(shi)例對象。

2、也即是(shi)(shi)說,在運行期間(jian),如果我(wo)們(men)要產生某個類(lei)的對象(xiang),Java虛擬機(ji)(JVM)會檢(jian)查該類(lei)型(xing)的Class對象(xiang)是(shi)(shi)否已被(bei)加(jia)載。如果沒有(you)(you)被(bei)加(jia)載,JVM會根(gen)據類(lei)的名稱找到.class文件并(bing)加(jia)載它。一旦某個類(lei)型(xing)的Class對象(xiang)已被(bei)加(jia)載到內存,就可以(yi)用它來(lai)產生該類(lei)型(xing)的所有(you)(you)對象(xiang)。

利用Class實例創建(jian)對象

 以前我(wo)(wo)們創建(jian)(jian)對象(xiang)都是用“new 類名(ming)()”的方式,現在(zai)我(wo)(wo)們先得到構(gou)造(zao)方法,并用構(gou)造(zao)方法來創建(jian)(jian)。現在(zai)我(wo)(wo)們要使用Consturctor(構(gou)造(zao)器)類:它代表(biao)某個類中的一個構(gou)造(zao)方法。

得到某個類所有的(de)構造(zao)方法

Constructor [] constructors = Class.forName("java.lang.String").getConstructors();

得(de)到某一(yi)個構造方法

Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);

注:參數是一個Class實例,即去拿匹配這樣參數的構造方法。

創建(jian)實例對(dui)象,用Constructor的newInstance方(fang)法

傳統方式:String str=new String(new StringBuffer("abc"));

反射方式:String str=(String) constructor.newInstance(new StringBuffer("abc"));

注(zhu):newInstance()方(fang)法參數可變長,請嘗(chang)試放多個參數。不(bu)合(he)適時(shi),報(bao)異(yi)常IllegalArgumentException。

上述原理可(ke)以(yi)下面示例來演練

class Test {

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

 Class c = Class.forName("java.lang.String");

Constructor constructor = c.getConstructor(StringBuffer.class);

String str = (String) constructor.newInstance(new StringBuffer("abc"));

System.out.println(str);

}

}

利用(yong)Constructor來(lai)創建(jian)實例與(yu)利用(yong)Class類來(lai)創建(jian)實例

class類(lei)也有創建(jian)實例的方法(fa),下面的例子進(jin)行(xing)了(le)展示。

此(ci)例來(lai)源(yuan)于//seahb.iteye.com/blog/855107。

import java.lang.reflect.Constructor;

class A {

private A() { // 將(jiang)private改為public試試

System.out.println("A's constructor A() is called.");

}

private A(int a, int b) {

System.out.println("A's constructor A(a,b) is called.");

System.out.println("a:" + a + " b:"; + b);

}

}

class B {

public static void main(String[] args) {

B b = new B();

System.out.println("通過Class.NewInstance()調用私有構造(zao)函數(shu):");

b.byClassNewInstance();

System.out.println("通過Constructor.newInstance()調用私有(you)構造(zao)函(han)數:");

b.byConstructorNewInstance();

}

/* 法一:通過Class.NewInstance()創(chuang)建新的類示例 */

private void byClassNewInstance() {

try {

Class c = Class.forName("A");

A a = (A) c.newInstance();//調用無(wu)參(can)構造方法。如果方法是(shi)私有的,則運行時會異常IllegalAccessException

} catch (Exception e) {

e.printStackTrace();

System.out.println("通過Class.NewInstance()調用構造(zao)方(fang)法【失(shi)敗】");

}

}

/*法二:通過Constructor.newInstance()創建新的類示例 */

private void byConstructorNewInstance() {

try {

Class c = Class.forName("A");

 Constructor c0 = c.getDeclaredConstructor();/* 調用無參構造方法 */

c0.setAccessible(true); //必須(xu)設置(zhi)一下可見性后就可調(diao)用(yong)了

A a0 = (A) c0.newInstance();//調(diao)用構造方法(fa)

System.out.println("成功(gong)1");

Constructor c1 = c.getDeclaredConstructor(new Class[] { int.class, int.class });/* 調用帶(dai)參構造方法 */

c1.setAccessible(true);

//A a1 = (A) c1.newInstance(new Object[] { 5, 6 });//參(can)數(shu)是對象數(shu)組(zu)

A a1 = (A) c1.newInstance(5, 6);//參數可連(lian)寫,因為newInstance()支(zhi)持可變參數

//A a1 = (A) c1.newInstance(5, 6,7);//參數(shu)若不合適(shi),則就報異常(chang)IllegalArgumentException

System.out.println("成功(gong)2");

} catch (Exception e) {

e.printStackTrace();

}

}

}

結論

class.newInstance和constructor.newInstance 區(qu)別

通過(guo)反(fan)射創建新的類示例,有兩(liang)種方式:

Class.newInstance()

Constructor.newInstance()

Class.newInstance() 只(zhi)能夠調用(yong)無參的(de)構造函(han)數(shu),即默認(ren)的(de)構造函(han)數(shu);

Constructor.newInstance() 可以根據傳入的參(can)數,調用任意(yi)構造(zao)(zao)構造(zao)(zao)函(han)數。

Class.newInstance() 要求被調用(yong)的(de)(de)構(gou)造函數(shu)是(shi)可見(jian)的(de)(de),也即必須是(shi)public類(lei)型的(de)(de);

Constructor.newInstance() 在特定的情(qing)況下,可以調用私有的構造函數。

如(ru)果(guo)被調(diao)用(yong)的(de)類的(de)構造(zao)(zao)函(han)數(shu)為默認的(de)構造(zao)(zao)函(han)數(shu),采(cai)用(yong)Class.newInstance()則是比較好的(de)選擇(ze),一句代碼就(jiu)OK;如(ru)果(guo)是調(diao)用(yong)帶參(can)構造(zao)(zao)函(han)數(shu)、私有構造(zao)(zao)函(han)數(shu),就(jiu)需(xu)要(yao)采(cai)用(yong)Constractor.newInstance(),兩種情況視使用(yong)情況而定(ding)。不過Java Totorial中推(tui)薦采(cai)用(yong)Constractor.newInstance()。

上一篇:讓你從根本上了解系統函數,簡單快速

下一篇:java編程中遇到的異常以及異常的一些處理

熱點文(wen)章推薦
華(hua)清學員就(jiu)業(ye)榜單
高薪學(xue)員經驗分享(xiang)
熱點新聞(wen)推薦
前臺(tai)專(zhuan)線:010-82525158 企業培(pei)訓洽談專線:010-82525379 院校(xiao)合作洽談專線(xian):010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部