色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

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

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

反射的概念

反射的概念是由 Smith 在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力。

換句話說,就是能夠得到代碼自身的特征。

換句話說,就是把類本身也看成是對象,包括類中的變量名、方法名、內部類、超類、包、修飾符等等,都可以通過代碼來得到并被看成是對象。

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

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

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

Constructor 類:提供關于類的單個構造方法的信息以及對它的訪問權限。這個類和 Field 類不同,Field 類封裝了反射類的屬性,而 Constructor 類則封裝了反射類的構造方法。

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

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

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

獲取Class類

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

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

獲取類自身有三種方式:

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

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

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

示例

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");//法三

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

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

}

}

運行結果為

true

true

解釋

1、運行結果為true說明虛擬機為某個類只會產生一份字節碼,將來用這份字節碼可以產生多個實例對象。

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

利用Class實例創建對象

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

得到某個類所有的構造方法

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

得到某一個構造方法

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

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

創建實例對象,用Constructor的newInstance方法

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

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

注:newInstance()方法參數可變長,請嘗試放多個參數。不合適時,報異常IllegalArgumentException。

上述原理可以下面示例來演練

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);

}

}

利用Constructor來創建實例與利用Class類來創建實例

class類也有創建實例的方法,下面的例子進行了展示。

此例來源于//seahb.iteye.com/blog/855107。

import java.lang.reflect.Constructor;

class A {

private A() { // 將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()調用私有構造函數:");

b.byClassNewInstance();

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

b.byConstructorNewInstance();

}

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

private void byClassNewInstance() {

try {

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

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

} catch (Exception e) {

e.printStackTrace();

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

}

}

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

private void byConstructorNewInstance() {

try {

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

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

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

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

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

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

c1.setAccessible(true);

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

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

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

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

} catch (Exception e) {

e.printStackTrace();

}

}

}

結論

class.newInstance和constructor.newInstance 區別

通過反射創建新的類示例,有兩種方式:

Class.newInstance()

Constructor.newInstance()

Class.newInstance() 只能夠調用無參的構造函數,即默認的構造函數;

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

Class.newInstance() 要求被調用的構造函數是可見的,也即必須是public類型的;

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

如果被調用的類的構造函數為默認的構造函數,采用Class.newInstance()則是比較好的選擇,一句代碼就OK;如果是調用帶參構造函數、私有構造函數,就需要采用Constractor.newInstance(),兩種情況視使用情況而定。不過Java Totorial中推薦采用Constractor.newInstance()。

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

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

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

回到頂部

主站蜘蛛池模板: 被黑人的巨茎日出白浆 | 99久久国产综合精品女同图片 | 亚洲精品污污 | 亚洲自偷自拍熟女另类 | FREE性开放小少妇 | 三级久久久| 久久精品无码一区二区小草 | 真实人与人性恔配视频 | 国产美女视频黄a片免费观看软件 | 美女爆乳裸体WWW免费网站 | 午夜成午夜成年片在线观看 | 免费国产女王调教在线视频 | 黑人亚洲娇小videos | 精品人妻系列无码专区 | 国产艳妇AV在线出轨 | 亚洲AV无码成人网站久久精品大 | 国产乱日| 老头天天吃我奶躁我的视频 | 亚洲精品无码久久毛片波多野吉衣 | 久久青青草原国产精品最新片 | 欧美XXXX做受欧美Gay | 日本免费无遮挡吸乳视频网站 | 护士裸体毛茸茸 | 国产尤物AV尤物在线看 | 果冻传媒一区二区天美传媒 | 亚洲AV色区一区二区三区 | 国产国语在线播放视频 | 人妻丰满熟妇AV无码区乱 | 亚洲色18成人网站www | 一级大片网站 | 精品国产一二三产品价格 | 免费无遮挡无码永久视频 | 99久久无色码中文字幕人妻蜜柚 | 五月天丁香色婷婷 | 日韩卡一卡二无线乱码新区仙踪林 | 久草久热 | 久久久久国产精品嫩草影院 | 在线吸色 | 陌陌影视在线观看免费 | 欧美肥臀大屁股MAGNET | 人妻少妇精品无码系列 |