偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java反射最佳實(shí)踐

移動(dòng)開(kāi)發(fā)
本文的例子都可以在示例代碼中看到并下載,如果喜歡請(qǐng)star,如果覺(jué)得有紕漏請(qǐng)?zhí)峤籭ssue,如果你有更好的點(diǎn)子可以提交pull request。本文的示例代碼主要是基于jOOR行編寫(xiě)的,如果想了解更多請(qǐng)查看這里的測(cè)試代碼。

本文的例子都可以在示例代碼中看到并下載,如果喜歡請(qǐng)star,如果覺(jué)得有紕漏請(qǐng)?zhí)峤籭ssue,如果你有更好的點(diǎn)子可以提交pull request。本文的示例代碼主要是基于jOOR行編寫(xiě)的,如果想了解更多請(qǐng)查看這里的測(cè)試代碼。

一、需求

今天一個(gè)“懶”程序員突然跑過(guò)來(lái)說(shuō):“反射好麻煩,我要提點(diǎn)需求。”

聽(tīng)到這句話(huà)后我就知道,今天一定不好過(guò)了,奇葩需求又來(lái)了。

我們之前寫(xiě)反射都是要這么寫(xiě):


  1. public static <T> T create(HttpRequest httpRequest) { 
  2.         Object httpRequestEntity = null
  3.         try { 
  4.             Class<T> httpRequestEntityCls = (Class<T>) Class.forName(HttpProcessor.PACKAGE_NAME + "." + HttpProcessor.CLASS_NAME); 
  5.             Constructor con = httpRequestEntityCls.getConstructor(HttpRequest.class); 
  6.             httpRequestEntity = con.newInstance(httpRequest); 
  7.         } catch (ClassNotFoundException e) { 
  8.             e.printStackTrace(); 
  9.         } catch (InstantiationException e) { 
  10.             e.printStackTrace(); 
  11.         } catch (IllegalAccessException e) { 
  12.             e.printStackTrace(); 
  13.         } catch (NoSuchMethodException e) { 
  14.             e.printStackTrace(); 
  15.         } catch (InvocationTargetException e) { 
  16.             e.printStackTrace(); 
  17.         } 
  18.         return (T) httpRequestEntity; 
  19.     } 

因?yàn)榉瓷湓陂_(kāi)發(fā)中很少用(做普通的業(yè)務(wù)開(kāi)發(fā)的話(huà)),僅僅在自己寫(xiě)一些框架和注解框架時(shí)會(huì)用到,所以對(duì)api總是不熟悉。每次用到api都要去網(wǎng)上查,查了后又得自己實(shí)驗(yàn)下,很不爽。更差勁的是這樣寫(xiě)法可讀性十分低下。我不希望這樣寫(xiě)反射,我希望反射能像


  1. String str = new String(); 

這樣簡(jiǎn)單,一行代碼搞定!。

此外,有很多人都說(shuō)反射影響性能,在開(kāi)發(fā)的時(shí)候要避免用反射。那么什么時(shí)候該用反射,什么時(shí)候不用反射呢?用什么方式來(lái)避免反射呢?如果不明白什么時(shí)候用反射,就很難將反射活學(xué)活用了。

二、分析

當(dāng)我們接到上面需求后,我長(zhǎng)舒一口氣,因?yàn)檫@回的需求還比較簡(jiǎn)單。

我相信有人會(huì)說(shuō):“反射就那幾個(gè)api,一直沒(méi)變過(guò),你就不會(huì)自己去查啊,覺(jué)得麻煩就別寫(xiě)代碼啊,不知道反射的內(nèi)部細(xì)節(jié)你怎么去提高呢?”
其實(shí)不然,重復(fù)寫(xiě)麻煩的代碼和提高自己的代碼能力是完全無(wú)關(guān)的,我實(shí)在不知道我們寫(xiě)了成千上萬(wàn)行的findViewById后除了知道類(lèi)要和xml文件綁定外,還學(xué)到了什么。

那么這回我們繼續(xù)來(lái)挑戰(zhàn)傳統(tǒng)思維和模板式代碼,來(lái)看看新一代的反射代碼應(yīng)該怎么寫(xiě),如何用一行代碼來(lái)反射出類(lèi)。
在做之前,來(lái)看看我們一般用反射來(lái)干嘛?

  1. 反射構(gòu)建出無(wú)法直接訪問(wèn)的類(lèi) 
  2. set或get到無(wú)法訪問(wèn)的類(lèi)變量 
  3. 調(diào)用不可訪問(wèn)的方法

三、解決方案

3.1 一行代碼寫(xiě)反射

作為一個(gè)Android程序員,索性就拿TextView這個(gè)類(lèi)開(kāi)刀吧。首先定義一個(gè)類(lèi)變量:


  1. TextView mTv; 

通過(guò)反射得到實(shí)例:


  1. // 有參數(shù),建立類(lèi) 
  2. mTv = Reflect.on(TextView.class).create(this).get(); 
  3.  
  4. // 通過(guò)類(lèi)全名得到類(lèi) 
  5. String word = Reflect.on("java.lang.String").create("Reflect TextView").get(); 
  6.  
  7. // 無(wú)參數(shù),建立類(lèi) 
  8. Fragment fragment = Reflect.on(Fragment.class).create().get(); 

通過(guò)反射調(diào)用方法:


  1. // 調(diào)用無(wú)參數(shù)方法 
  2. L.d("call getText() : " + Reflect.on(mTv).call("getText").toString()); 
  3.  
  4. // 調(diào)用有參數(shù)方法 
  5. Reflect.on(mTv).call("setTextColor"0xffff0000); 

通過(guò)反射get、set類(lèi)變量

TextView中有個(gè)mText變量,來(lái)看看我們?cè)趺唇咏?/p>


  1. // 設(shè)置參數(shù) 
  2. Reflect.on(mTv).set("mText""---------- new Reflect TextView ----------"); 
  3.  
  4. // 獲得參數(shù) 
  5. L.d("setgetParam is " + Reflect.on(mTv).get("mText")); 

3.2 什么時(shí)候該用反射,什么時(shí)候不用反射

又到了這樣權(quán)衡利弊的時(shí)候了,首先我們明確,在日常開(kāi)發(fā)中盡量不要用反射,除非遇到了必須要通過(guò)反射才能調(diào)用的方法。比如我在做一個(gè)下拉通知中心功能的時(shí)候就遇到了這樣的情況。系統(tǒng)沒(méi)有提供api,所以我們只能通過(guò)反射進(jìn)行調(diào)用,所以我自己寫(xiě)了這樣一段代碼:

  1. <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/> 
  2. private static void doInStatusBar(Context mContext, String methodName) { 
  3.         try { 
  4.             Object service = mContext.getSystemService("statusbar"); 
  5.             Method expand = service.getClass().getMethod(methodName); 
  6.             expand.invoke(service); 
  7.         } catch (Exception e) { 
  8.             e.printStackTrace(); 
  9.         } 
  10.     } 
  11.  
  12.     /** 
  13.      * 顯示消息中心 
  14.      */ 
  15.     public static void openStatusBar(Context mContext) { 
  16.         // 判斷系統(tǒng)版本號(hào) 
  17.         String methodName = (VERSION.SDK_INT <= 16) ? "expand" : "expandNotificationsPanel"
  18.         doInStatusBar(mContext, methodName); 
  19.     } 
  20.  
  21.     /** 
  22.      * 關(guān)閉消息中心 
  23.      */ 
  24.     public static void closeStatusBar(Context mContext) { 
  25.         // 判斷系統(tǒng)版本號(hào) 
  26.         String methodName = (VERSION.SDK_INT <= 16) ? "collapse" : "collapsePanels"
  27.         doInStatusBar(mContext, methodName); 
  28.     } 
 

先來(lái)看看利用jOOR寫(xiě)的doInStatusBar方法會(huì)簡(jiǎn)潔到什么程度:


  1. private static void doInStatusBar(Context mContext, String methodName) { 
  2.         Object service = mContext.getSystemService("statusbar"); 
  3.         Reflect.on(service).call(methodName); 
  4.     } 

哇,就一行代碼啊,很爽吧~

爽完了,我們就來(lái)看看反射問(wèn)題吧。因?yàn)椴皇窍到y(tǒng)給出的api,所以谷歌在不同的版本上用了不同的方法名來(lái)做處理,用反射的話(huà)我們就必須進(jìn)行版本的判斷,這是需要注意的,此外反射在性能方面確實(shí)不好,這里需要謹(jǐn)慎。

我的建議:

如果一個(gè)類(lèi)中有很多地方都是private的,而你的需求都需要依賴(lài)這些方法或者變量,那么比起用反射,推薦把這個(gè)類(lèi)復(fù)制出來(lái),變成自己的類(lèi),像是toolbar這樣的類(lèi)就可以進(jìn)行這樣的操作。

在自己寫(xiě)框架的時(shí)候,我們肯定會(huì)用到反射,很簡(jiǎn)單的例子就是事件總線和注解框架,翔哥就說(shuō)過(guò)一句話(huà):無(wú)反射,無(wú)框架。也正因?yàn)槭亲约簩?xiě)的框架,所以通過(guò)反射調(diào)用的方法名和參數(shù)一般不會(huì)變,更何況做運(yùn)行時(shí)注解框架的話(huà),反射肯定會(huì)出現(xiàn)。在這種情況下千萬(wàn)不要害怕反射,索性放心大膽的做。因?yàn)樗鼤?huì)讓你完成很多不可能完成的任務(wù)。

總結(jié)下來(lái)就是:

實(shí)際進(jìn)行日常開(kāi)發(fā)的時(shí)候盡量少用反射,可以通過(guò)復(fù)制原始類(lèi)的形式來(lái)避免反射。在寫(xiě)框架時(shí),不避諱反射,在關(guān)鍵時(shí)利用反射來(lái)助自己一臂之力。

四、后記

我們終于完成了用一行代碼寫(xiě)反射,避免了很多無(wú)意義的模板式代碼。需要再次說(shuō)明的是,本文是依據(jù)jOOR 進(jìn)行編寫(xiě)的,這里有原項(xiàng)目readme的中文翻譯。

jOOR是我無(wú)意中遇到的開(kāi)源庫(kù),***次見(jiàn)到它時(shí)我就知道這個(gè)是我想要的,因?yàn)槟菚r(shí)候我被反射搞的很亂,而它簡(jiǎn)潔的編碼方式給我?guī)?lái)了新的思考,大大提高了代碼可讀性。順便一說(shuō),作者人比較好(就是死活不愿意讓我放入中文的readme),技術(shù)也很不錯(cuò)。該項(xiàng)目有很詳細(xì)的測(cè)試用例,并且還給出了幾個(gè)類(lèi)似的反射調(diào)用封裝庫(kù)??梢?jiàn)作者在寫(xiě)庫(kù)時(shí)做了大量的調(diào)研和測(cè)試工作,讓我們可以放心的運(yùn)用該庫(kù)(其實(shí)就兩個(gè)類(lèi))。

本文希望帶給大家一個(gè)反射的新思路,給出一個(gè)最簡(jiǎn)單實(shí)用的反射寫(xiě)法,希望能被大家迅速運(yùn)用到實(shí)踐中去。更加重要的是,通過(guò)對(duì)jOOR的分析,讓我知道了寫(xiě)庫(kù)前應(yīng)該調(diào)研類(lèi)似的庫(kù),而不是完全的創(chuàng)造新輪子,調(diào)研和測(cè)試是代碼穩(wěn)定性的重要保障。

責(zé)任編輯:倪明 來(lái)源: github
相關(guān)推薦

2017-03-24 09:44:33

Java反射機(jī)制

2017-05-17 15:28:15

Java反射機(jī)制

2011-08-18 11:05:21

jQuery

2023-07-21 01:12:30

Reactfalse?變量

2024-10-10 09:46:18

2012-08-09 09:10:56

代碼審查代碼

2024-08-21 08:02:47

2014-06-09 15:50:08

2011-12-21 13:35:39

JavaJFreeChart

2014-08-19 10:06:53

IAP

2009-07-29 17:52:29

ibmdwJava

2011-12-21 13:52:27

JavaJFreeChart

2023-09-11 08:50:03

Maven工具關(guān)系管理

2023-09-13 08:00:00

JavaScript循環(huán)語(yǔ)句

2018-02-06 09:05:25

Java異常處理代碼

2018-01-12 14:37:34

Java代碼實(shí)踐

2018-05-10 15:06:43

Java Web分層實(shí)踐

2025-06-06 02:00:00

2025-03-19 09:04:39

2010-02-04 11:55:27

ibmdwDB2
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)