激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

香港云服务器
服務(wù)器之家 - 編程語言 - JAVA教程 - Java反射機(jī)制詳解

Java反射機(jī)制詳解

2020-03-09 12:53西電一枝花 JAVA教程

這篇文章主要介紹了Java反射機(jī)制,首先簡單介紹了反射機(jī)制的預(yù)備知識,進(jìn)一步分析了Java反射機(jī)制的原理、實(shí)現(xiàn)技巧與應(yīng)用方法,需要的朋友可以參考下

本文較為詳細(xì)的分析了Java反射機(jī)制。分享給大家供大家參考,具體如下:

一、預(yù)先需要掌握的知識(java虛擬機(jī))

java虛擬機(jī)的方法區(qū):

java虛擬機(jī)有一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū),這個(gè)數(shù)據(jù)區(qū)又被分為方法區(qū),堆區(qū)和棧區(qū),我們這里需要了解的主要是方法區(qū)。方法區(qū)的主要作用是存儲被裝載的類 的類型信息,當(dāng)java虛擬機(jī)裝載某個(gè)類型的時(shí)候,需要類裝載器定位相應(yīng)的class文件,然后將其讀入到j(luò)ava虛擬機(jī)中,緊接著虛擬機(jī)提取class 中的類型信息,將這些信息存儲到方法區(qū)中。這些信息主要包括:

1、這個(gè)類型的全限定名

2、這個(gè)類型的直接超類的全限定名

3、這個(gè)類型是類類型還是接口類型

4、這個(gè)類型的訪問修飾符

5、任何直接超接口的全限定名的有序列表

6、該類型的常量池

7、字段信息

8、方法信息

9、除了常量以外的所有類變量

10、一個(gè)到class類的引用

等等(讀者可以參考《深入java虛擬機(jī)》這本書的敘述)

Class類:

Class類是一個(gè)非常重要的java基礎(chǔ)類,每當(dāng)裝載一個(gè)新的類型的時(shí)候,java虛擬機(jī)都會(huì)在java堆中創(chuàng)建一個(gè)對應(yīng)于新類型的Class實(shí)例,該實(shí)例就代表此類型,通過該Class實(shí)例我們就可以訪問該類型的基本信息。上面說到在方法區(qū)中會(huì)存儲某個(gè)被裝載類的類型信息,我們就可以通過 Class實(shí)例來訪問這些信息。比如,對于上面說到的信息Class中都有對應(yīng)的方法,如下:

1、getName();這個(gè)類型的全限定名

2、getSuperClass();這個(gè)類型的直接超類的全限定名

3、isInterface();這個(gè)類型是類類型還是接口類型

4、getTypeParamters();這個(gè)類型的訪問修飾符

5、getInterfaces();任何直接超接口的全限定名的有序列表

6、getFields();字段信息

7、getMethods();方法信息

等等(讀者可以自己參看jdk幫助文檔,得到更多的信息)

二、java反射詳解

反射的概念:所謂的反射就是java語言在運(yùn)行時(shí)擁有一項(xiàng)自觀的能力,反射使您的程序代碼能夠得到裝載到JVM中的類的內(nèi)部信息,允許您執(zhí)行程序時(shí)才得到需要類的內(nèi)部信息,而不是在編寫代碼的時(shí)候就必須要知道所需類的內(nèi)部信息,這使反射成為構(gòu)建靈活的應(yīng)用的主要工具。

反射的常用類和函數(shù):Java反射機(jī)制的實(shí)現(xiàn)要借助于4個(gè)類:Class,Constructor,F(xiàn)ield,Method;其中class代 表的是類對象,Constructor-類的構(gòu)造器對象,F(xiàn)ield-類的屬性對象,Method-類的方法對象,通過這四個(gè)對象我們可以粗略的看到一個(gè)類的各個(gè)組成部分。其中最核心的就是Class類,它是實(shí)現(xiàn)反射的基礎(chǔ),它包含的方法我們在第一部分已經(jīng)進(jìn)行了基本的闡述。應(yīng)用反射時(shí)我們最關(guān)心的一般是一個(gè)類的構(gòu)造器、屬性和方法,下面我們主要介紹Class類中針對這三個(gè)元素的方法:

1、得到構(gòu)造器的方法

Constructor getConstructor(Class[] params) -- 獲得使用特殊的參數(shù)類型的公共構(gòu)造函數(shù),

Constructor[] getConstructors() -- 獲得類的所有公共構(gòu)造函數(shù)

Constructor getDeclaredConstructor(Class[] params) -- 獲得使用特定參數(shù)類型的構(gòu)造函數(shù)(與接入級別無關(guān))

Constructor[] getDeclaredConstructors() -- 獲得類的所有構(gòu)造函數(shù)(與接入級別無關(guān))

2、獲得字段信息的方法

Field getField(String name) -- 獲得命名的公共字段

Field[] getFields() -- 獲得類的所有公共字段

Field getDeclaredField(String name) -- 獲得類聲明的命名的字段

Field[] getDeclaredFields() -- 獲得類聲明的所有字段
3、獲得方法信息的方法

Method getMethod(String name, Class[] params) -- 使用特定的參數(shù)類型,獲得命名的公共方法

Method[] getMethods() -- 獲得類的所有公共方法

Method getDeclaredMethod(String name, Class[] params) -- 使用特寫的參數(shù)類型,獲得類聲明的命名的方法

Method[] getDeclaredMethods() -- 獲得類聲明的所有方法

應(yīng)用反射的基本步驟:

1、獲得你想操作的類的Class對象;

方法一:Classc=Class.forName("java.lang.String") //這種方式獲得類的Class對象需要 包名.類名

方法二:對于基本數(shù)據(jù)類型可以用形如Class c=int.class或Class c=Integer.TYPE的語句

方法三:Class c=MyClass.class

2、調(diào)用Class中的方法得到你想得到的信息集合,如調(diào)用getDeclaredFields()方法得到類的所有屬性;

3、處理第2步中得到的信息,然后進(jìn)行你想做的實(shí)際操作。

反射實(shí)例:

下面我將針對類的構(gòu)造器、屬性和方法分別舉三個(gè)例子,向大家演示一下反射的應(yīng)用過程。

1、構(gòu)造器

步驟為:通過反射機(jī)制得到某個(gè)類的構(gòu)造器,然后調(diào)用該構(gòu)造器創(chuàng)建該類的一個(gè)實(shí)例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.lang.reflect.*;
public class ConstructorDemo{
  public ConstructorDemo(){ }
  public ConstructorDemo(int a, int b){
   System.out.println("a="+a+"b="+b);
  }
  public static void main(String args[]){
    try {
      Class cls =Class.forName("包名.ConstructorDemo");
      Class partypes[] =new Class[2]; partypes[0] = Integer.TYPE; 
      partypes[1] =Integer.TYPE;
      Constructor ct=cls.getConstructor(partypes);
      Object arglist[] =new Object[2];
      arglist[0] = newInteger(37);
      arglist[1] = newInteger(47);
      Object retobj = ct.newInstance(arglist);
     } catch (Throwable e) {
      System.err.println(e);}
     }
  }

2、屬性

步驟為:通過反射機(jī)制得到某個(gè)類的某個(gè)屬性,然后改變對應(yīng)于這個(gè)類的某個(gè)實(shí)例的該屬性值

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.lang.reflect.*;
public class FieldDemo1{
 public double d;
 public static void main(String args[]){
 try {
  Class cls = Class.forName("FieldDemo1");
  Field fld = cls.getField("d");
  FieldDemo1 fobj = new FieldDemo1();
  System.out.println("d = " + fobj.d);
  fld.setDouble(fobj, 12.34);
  System.out.println("d = " + fobj.d);
 } catch (Throwable e){
  System.err.println(e); }
 }
}

3、方法

步驟為:通過反射機(jī)制得到某個(gè)類的某個(gè)方法,然后調(diào)用對應(yīng)于這個(gè)類的某個(gè)實(shí)例的該方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//通過使用方法的名字調(diào)用方法
import java.lang.reflect.*;
public class MethodDemo1{
 public int add(int a, int b){
 return a + b;
 }
 public static void main(String args[]){
  try {
   Class cls =Class.forName("MethodDemo1");
   Class partypes[] = new Class[2];
   partypes[0] = Integer.TYPE;
   partypes[1] = Integer.TYPE;
   Method meth = cls.getMethod("add",partypes);
   MethodDemo1 methobj = new MethodDemo1();
   Object arglist[] = new Object[2];
   arglist[0] = new Integer(37);
   arglist[1] = new Integer(47);
   Object retobj= meth.invoke(methobj, arglist);
   Integer retval = (Integer)retobj;
   System.out.println(retval.intValue());
  } catch (Throwable e) {
   System.err.println(e);
  }
 }
}

三、java反射的應(yīng)用(Hibernate)

我們在第二部分中對java反射進(jìn)行了比較系統(tǒng)的闡述,也舉了幾個(gè)簡單的實(shí)例,下面我們就來討論一下java反射的具體應(yīng)用。前面我們已經(jīng)知 道,Java反射機(jī)制提供了一種動(dòng)態(tài)鏈接程序組件的多功能方法,它允許程序創(chuàng)建和控制任何類的對象(根據(jù)安全性限制)之前,無需提前硬編碼目標(biāo)類。這些特 性使得反射特別適用于創(chuàng)建以非常普通的方式與對象協(xié)作的庫。例如,反射經(jīng)常在持續(xù)存儲對象為數(shù)據(jù)庫、XML或其它外部格式的框架中使用。下面我們就已 Hibernate框架為例像大家闡述一下反射的重要意義。

Hibernate是一個(gè)屏蔽了JDBC,實(shí)現(xiàn)了ORM的java框架,利用該框架我們可以拋棄掉繁瑣的sql語句而是利用Hibernate中 Session類的save()方法直接將某個(gè)類的對象存到數(shù)據(jù)庫中,也就是所涉及到sql語句的那些代碼Hibernate幫我們做了。這時(shí)候就出現(xiàn)了 一個(gè)問題,Hibernate怎樣知道他要存的某個(gè)對象都有什么屬性呢?這些屬性都是什么類型呢?如此,它在向數(shù)據(jù)庫中存儲該對象屬性時(shí)的sql語句該怎么構(gòu)造呢?解決這個(gè)問題的利器就是我們的java反射!

下面我們以一個(gè)例子來進(jìn)行闡述,比如我們定義了一個(gè)User類,這個(gè)User類中有20個(gè)屬性和這些屬性的get和set方法,相應(yīng)的在數(shù)據(jù)庫中 有一個(gè)User表,這個(gè)User表中對應(yīng)著20個(gè)字段。假設(shè)我們從User表中提取了一條記錄,現(xiàn)在需要將這條記錄的20個(gè)字段的內(nèi)容分別賦給一個(gè) User對象myUser的20個(gè)屬性,而Hibernate框架在編譯的時(shí)候并不知道這個(gè)User類,他無法直接調(diào)用myUser.getXXX或者 myUser.setXXX方法,此時(shí)就用到了反射,具體處理過程如下:

1、根據(jù)查詢條件構(gòu)造PreparedStament語句,該語句返回20個(gè)字段的值;

2、Hibernate通過讀取配置文件得到User類的屬性列表list(是一個(gè)String數(shù)組)以及這些屬性的類型;

3、創(chuàng)建myUser所屬類的Class對象c;c=myUser.getClass();

4、構(gòu)造一個(gè)for循環(huán),循環(huán)的次數(shù)為list列表的長度;

4.1、讀取list[i]的值,然后構(gòu)造對應(yīng)該屬性的set方法;

4.2、判斷l(xiāng)ist[i]的類型XXX,調(diào)用PreparedStament語句中的getXXX(i),進(jìn)而得到i出字段的值;

4.3、將4.2中得到的值作為4.1中得到的set方法的參數(shù),這樣就完成了一個(gè)字段像一個(gè)屬性的賦值,如此循環(huán)即可;

看到了吧,這就是反射的功勞,如果沒有反射很難想象如果完成同樣的功能會(huì)有多么難!但是反射也有缺點(diǎn),比如性能比較低、安全性比較復(fù)雜等,這里就不在討論這些東西,感興趣的讀者可以在網(wǎng)上找到答案,有很多的!

希望本文所述對大家Java程序設(shè)計(jì)有所幫助。

延伸 · 閱讀

精彩推薦
352
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 精品国产一区二区三区在线观看 | 午夜国产精品成人 | 成人毛片免费视频 | 国产一区二区欧美精品 | 91视频第一页 | 久久精品国产99国产精品澳门 | 日韩在线激情 | 成人在线视频国产 | 国产亚洲欧美日韩在线观看不卡 | 日韩区在线 | 国产成人精品免费视频大全最热 | 欧美一级毛片欧美一级成人毛片 | 日韩一级毛毛片 | 九九精品在线观看视频 | 日韩精品中文字幕在线观看 | 精品一区二区三区免费爱 | 精品在线观看一区二区 | 在线91视频 | 激情视频导航 | 国产成人自拍视频在线 | 欧美一区二区黄色片 | 狠狠久久伊人中文字幕 | 免费一级欧美在线观看视频 | 一二区电影 | 欧美a区| 91嫩草丨国产丨精品入口 | 免费观看的毛片手机视频 | a网在线 | 91久久极品少妇韩国 | 欧美一级爱爱 | 久久久一区二区三区四区 | 久久久久久久久久久久久久久伊免 | 欧美中文在线 | 国产成人精品午夜视频' | 午夜视频在线在免费 | 免费黄色小视频网站 | 成人三级视频在线观看 | 成年人免费黄色片 | 韩国精品视频在线观看 | 成熟女人特级毛片www免费 | 中文字幕在线观看国产 |