国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Reflection:Java反射機(jī)制的應(yīng)用場(chǎng)景

浠ラ箍 / 2450人閱讀

近期在維護(hù)公司項(xiàng)目的時(shí)候遇到一個(gè)問題,因?yàn)閷?shí)體類中的 set 方法涉及到了業(yè)務(wù)邏輯,因此在給對(duì)象賦值的過程中不能夠使用 set 方法,為了實(shí)現(xiàn)功能,所以采用了反射的機(jī)制給對(duì)象屬性賦值,借此機(jī)會(huì)也了解了反射的一些具體用法和使用場(chǎng)景,分以下兩點(diǎn)對(duì)反射進(jìn)行分析:

反射的優(yōu)勢(shì)和劣勢(shì)

反射的應(yīng)用場(chǎng)景

反射的優(yōu)勢(shì)和劣勢(shì)

??個(gè)人理解,反射機(jī)制實(shí)際上就是上帝模式,如果說方法的調(diào)用是 Java 正確的打開方式,那反射機(jī)制就是上帝偷偷開的后門,只要存在對(duì)應(yīng)的class,一切都能夠被調(diào)用。

??那上帝為什么要打開這個(gè)后門呢?這涉及到了靜態(tài)和動(dòng)態(tài)的概念

靜態(tài)編譯:在編譯時(shí)確定類型,綁定對(duì)象

動(dòng)態(tài)編譯:運(yùn)行時(shí)確定類型,綁定對(duì)象

??兩者的區(qū)別在于,動(dòng)態(tài)編譯可以最大程度地支持多態(tài),而多態(tài)最大的意義在于降低類的耦合性,因此反射的優(yōu)點(diǎn)就很明顯了:解耦以及提高代碼的靈活性。

??因此,反射的優(yōu)勢(shì)和劣勢(shì)分別在于:

優(yōu)勢(shì)

運(yùn)行期類型的判斷,動(dòng)態(tài)類加載:提高代碼靈活度

劣勢(shì)

性能瓶頸:反射相當(dāng)于一系列解釋操作,通知 JVM 要做的事情,性能比直接的java代碼要慢很多

反射的應(yīng)用場(chǎng)景

??在我們平時(shí)的項(xiàng)目開發(fā)過程中,基本上很少會(huì)直接使用到反射機(jī)制,但這不能說明反射機(jī)制沒有用,實(shí)際上有很多設(shè)計(jì)、開發(fā)都與反射機(jī)制有關(guān),例如模塊化的開發(fā),通過反射去調(diào)用對(duì)應(yīng)的字節(jié)碼;動(dòng)態(tài)代理設(shè)計(jì)模式也采用了反射機(jī)制,還有我們?nèi)粘J褂玫?Spring/Hibernate 等框架,也是利用CGLIB 反射機(jī)制才得以實(shí)現(xiàn),下面就舉例最常見的兩個(gè)例子,來說明反射機(jī)制的強(qiáng)大之處:

JDBC 的數(shù)據(jù)庫(kù)的連接

在JDBC 的操作中,如果要想進(jìn)行數(shù)據(jù)庫(kù)的連接,則必須按照以上的幾步完成

通過Class.forName()加載數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序 (通過反射加載,前提是引入相關(guān)了Jar包)

通過 DriverManager 類進(jìn)行數(shù)據(jù)庫(kù)的連接,連接的時(shí)候要輸入數(shù)據(jù)庫(kù)的連接地址、用戶名、密碼

通過Connection 接口接收連接

public class ConnectionJDBC {  
  
    /** 
     * @param args 
     */  
    //驅(qū)動(dòng)程序就是之前在classpath中配置的JDBC的驅(qū)動(dòng)程序的JAR 包中  
    public static final String DBDRIVER = "com.mysql.jdbc.Driver";  
    //連接地址是由各個(gè)數(shù)據(jù)庫(kù)生產(chǎn)商多帶帶提供的,所以需要多帶帶記住  
    public static final String DBURL = "jdbc:mysql://localhost:3306/test";  
    //連接數(shù)據(jù)庫(kù)的用戶名  
    public static final String DBUSER = "root";  
    //連接數(shù)據(jù)庫(kù)的密碼  
    public static final String DBPASS = "";  
      
      
    public static void main(String[] args) throws Exception {  
        Connection con = null; //表示數(shù)據(jù)庫(kù)的連接對(duì)象  
        Class.forName(DBDRIVER); //1、使用CLASS 類加載驅(qū)動(dòng)程序 ,反射機(jī)制的體現(xiàn) 
        con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、連接數(shù)據(jù)庫(kù)  
        System.out.println(con);  
        con.close(); // 3、關(guān)閉數(shù)據(jù)庫(kù)  
    }  

Spring 框架的使用

??在 Java的反射機(jī)制在做基礎(chǔ)框架的時(shí)候非常有用,行內(nèi)有一句這樣的老話:反射機(jī)制是Java框架的基石。一般應(yīng)用層面很少用,不過這種東西,現(xiàn)在很多開源框架基本都已經(jīng)封裝好了,自己基本用不著寫。典型的除了hibernate之外,還有spring也用到很多反射機(jī)制。最經(jīng)典的就是xml的配置模式。

Spring 通過 XML 配置模式裝載 Bean 的過程:

將程序內(nèi)所有 XML 或 Properties 配置文件加載入內(nèi)存中

Java類里面解析xml或properties里面的內(nèi)容,得到對(duì)應(yīng)實(shí)體類的字節(jié)碼字符串以及相關(guān)的屬性信息

使用反射機(jī)制,根據(jù)這個(gè)字符串獲得某個(gè)類的Class實(shí)例

動(dòng)態(tài)配置實(shí)例的屬性

Spring這樣做的好處是:

不用每一次都要在代碼里面去new或者做其他的事情

以后要改的話直接改配置文件,代碼維護(hù)起來就很方便了

有時(shí)為了適應(yīng)某些需求,Java類里面不一定能直接調(diào)用另外的方法,可以通過反射機(jī)制來實(shí)現(xiàn)

模擬 Spring 加載 XML 配置文件:

public class BeanFactory {
       private Map beanMap = new HashMap();
       /**
       * bean工廠的初始化.
       * @param xml xml配置文件
       */
       public void init(String xml) {
              try {
                     //讀取指定的配置文件
                     SAXReader reader = new SAXReader();
                     ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                     //從class目錄下獲取指定的xml文件
                     InputStream ins = classLoader.getResourceAsStream(xml);
                     Document doc = reader.read(ins);
                     Element root = doc.getRootElement();  
                     Element foo;
                    
                     //遍歷bean
                     for (Iterator i = root.elementIterator("bean"); i.hasNext();) {  
                            foo = (Element) i.next();
                            //獲取bean的屬性id和class
                            Attribute id = foo.attribute("id");  
                            Attribute cls = foo.attribute("class");
                           
                            //利用Java反射機(jī)制,通過class的名稱獲取Class對(duì)象
                            Class bean = Class.forName(cls.getText());
                           
                            //獲取對(duì)應(yīng)class的信息
                            java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
                            //獲取其屬性描述
                            java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
                            //設(shè)置值的方法
                            Method mSet = null;
                            //創(chuàng)建一個(gè)對(duì)象
                            Object obj = bean.newInstance();
                           
                            //遍歷該bean的property屬性
                            for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {  
                                   Element foo2 = (Element) ite.next();
                                   //獲取該property的name屬性
                                   Attribute name = foo2.attribute("name");
                                   String value = null;
                                  
                                   //獲取該property的子元素value的值
                                   for(Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) {
                                          Element node = (Element) ite1.next();
                                          value = node.getText();
                                          break;
                                   }
                                  
                                   for (int k = 0; k < pd.length; k++) {
                                          if (pd[k].getName().equalsIgnoreCase(name.getText())) {
                                                 mSet = pd[k].getWriteMethod();
                                                 //利用Java的反射極致調(diào)用對(duì)象的某個(gè)set方法,并將值設(shè)置進(jìn)去
                                                 mSet.invoke(obj, value);
                                          }
                                   }
                            }
                           
                            //將對(duì)象放入beanMap中,其中key為id值,value為對(duì)象
                            beanMap.put(id.getText(), obj);
                     }
              } catch (Exception e) {
                     System.out.println(e.toString());
              }
       }
      
       //other codes
}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/67352.html

相關(guān)文章

  • ReflectionJava反射機(jī)制基礎(chǔ)

    摘要:反射機(jī)制是什么反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為語言的反射機(jī)制反射機(jī)制能做什么反射機(jī)制主要提供了以下功 反射機(jī)制是什么 反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種...

    hizengzeng 評(píng)論0 收藏0
  • Java動(dòng)態(tài)性(2) - 之反射機(jī)制(Reflection)

    摘要:的動(dòng)態(tài)性反射機(jī)制動(dòng)態(tài)編譯動(dòng)態(tài)執(zhí)行代碼動(dòng)態(tài)字節(jié)碼操作動(dòng)態(tài)語言程序運(yùn)行時(shí)可以改變程序得結(jié)構(gòu)或變量類型典型語言等如下代碼不是動(dòng)態(tài)語言但有一定的動(dòng)態(tài)性我們可以利用反射機(jī)制字節(jié)碼操作獲得類似動(dòng)態(tài)語言的特性的動(dòng)態(tài)性讓編程的時(shí)候更加靈活反射機(jī)制反射機(jī)制指 1.Java的動(dòng)態(tài)性 反射機(jī)制 動(dòng)態(tài)編譯 動(dòng)態(tài)執(zhí)行JavaScript代碼 動(dòng)態(tài)字節(jié)碼操作 2.動(dòng)態(tài)語言 程序運(yùn)行時(shí),可以改變程序得結(jié)構(gòu)或變量...

    妤鋒シ 評(píng)論0 收藏0
  • Java 反射(Reflection)

    摘要:效率運(yùn)行效率使用反射減低程序的運(yùn)行效率。開發(fā)效率由于反射運(yùn)用到各個(gè)框架中,大大加快了開發(fā)的效率。 反射的核心就是Class對(duì)象,每一個(gè)類被jvm加載都會(huì)有一個(gè)對(duì)應(yīng)的class對(duì)象,這個(gè)class對(duì)象包含了這個(gè)類的結(jié)構(gòu)信息,反射就是會(huì)通過反射api反復(fù)操作這個(gè)class對(duì)象(屬性,方法,注解,構(gòu)造器,泛型),但是反射會(huì)降低程序的運(yùn)行效率,比普通方法要慢30倍,通過setAccessble...

    shengguo 評(píng)論0 收藏0
  • PHP高級(jí)特性-反射Reflection以及Factory工廠設(shè)計(jì)模式結(jié)合使用[代碼實(shí)例]

    摘要:反射提供給面向?qū)ο缶幊炭梢宰允〉哪芰Γ捶瓷洹T诤?jiǎn)單工廠模式中,根據(jù)傳遞的參數(shù)來返回不同的類的實(shí)例簡(jiǎn)單工廠模式又稱為靜態(tài)工廠方法模式。也就是簡(jiǎn)單工廠模式工廠工廠類。PHP高級(jí)特性-反射以及工廠設(shè)計(jì)模式的結(jié)合使用 [結(jié)合 Laravel-Admin 代碼實(shí)例講解]利用反射來實(shí)現(xiàn)工廠模式的生產(chǎn)而無需創(chuàng)建特定的工廠類本文地址http://janrs.com/?p=833轉(zhuǎn)載無需經(jīng)過作者本人授權(quán)轉(zhuǎn)載...

    番茄西紅柿 評(píng)論0 收藏2637
  • 最最最常見Java面試題總結(jié)——第二周

    摘要:與都繼承自類,在中也是使用字符數(shù)組保存字符串,,這兩種對(duì)象都是可變的。采用字節(jié)碼的好處語言通過字節(jié)碼的方式,在一定程度上解決了傳統(tǒng)解釋型語言執(zhí)行效率低的問題,同時(shí)又保留了解釋型語言可移植的特點(diǎn)。 String和StringBuffer、StringBuilder的區(qū)別是什么?String為什么是不可變的? String和StringBuffer、StringBuilder的區(qū)別 可變性...

    yearsj 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

浠ラ箍

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<