最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解提高使用Java反射的效率方法

 更新時(shí)間:2019年04月29日 08:29:49   投稿:laozhang  
在本篇文章中小編給大家分享了關(guān)于提高使用Java反射的效率的相關(guān)知識(shí)點(diǎn)和方法,需要的朋友們參考下。

在我們平時(shí)的工作或者面試中,都會(huì)經(jīng)常遇到“反射”這個(gè)知識(shí)點(diǎn),通過(guò)“反射”我們可以動(dòng)態(tài)的獲取到對(duì)象的信息以及靈活的調(diào)用對(duì)象方法等,但是在使用的同時(shí)又伴隨著另一種聲音的出現(xiàn),那就是“反射”很慢,要少用。難道反射真的很慢?那跟我們平時(shí)正常創(chuàng)建對(duì)象調(diào)用方法比慢多少? 估計(jì)很多人都沒去測(cè)試過(guò),只是”道聽途說(shuō)“。下面我們就直接通過(guò)一些測(cè)試用例來(lái)直觀的感受一下”反射“。
正文

準(zhǔn)備測(cè)試對(duì)象

下面先定義一個(gè)測(cè)試的類TestUser,只有id跟name屬性,以及它們的getter/setter方法,另外還有一個(gè)自定義的sayHi方法。

public class TestUser { private Integer id; private String name; 

 public String sayHi(){  return "hi";

 } public Integer getId() {  return id;

 } public void setId(Integer id) {  this.id = id;

 } public String getName() {  return name;

 } public void setName(String name) {  this.name = name;

 }

}

測(cè)試創(chuàng)建100萬(wàn)個(gè)對(duì)象

// 通過(guò)普通方式創(chuàng)建TestUser對(duì)象@Testpublic void testCommon(){ long start = System.currentTimeMillis();

 TestUser user = null; int i = 0; while(i<1000000){

  ++i;

  user = new TestUser();

 } long end = System.currentTimeMillis();

 System.out.println("普通對(duì)象創(chuàng)建耗時(shí):"+(end - start ) + "ms");

}//普通對(duì)象創(chuàng)建耗時(shí):10ms
// 通過(guò)反射方式創(chuàng)建TestUser對(duì)象@Testpublic void testReflexNoCache() throws Exception { long start = System.currentTimeMillis();

 TestUser user = null; int i = 0; while(i<1000000){

  ++i;

  user = (TestUser) Class.forName("ReflexDemo.TestUser").newInstance();

 } long end = System.currentTimeMillis();

 System.out.println("無(wú)緩存反射創(chuàng)建對(duì)象耗時(shí):"+(end - start ) + "ms");

}//無(wú)緩存反射創(chuàng)建對(duì)象耗時(shí):926ms

在上面這兩個(gè)測(cè)試方法中,筆者各自測(cè)了5次,把他們消耗的時(shí)間取了一個(gè)平均值,在輸出結(jié)果中可以看到一個(gè)是10ms,一個(gè)是926ms,在創(chuàng)建100W個(gè)對(duì)象的情況下,反射居然慢了90倍左右。wtf?差距居然這么大?難道反射真的這么慢?下面筆者換一種反射的姿勢(shì),繼續(xù)測(cè)試一下,看看結(jié)果如何

// 通過(guò)緩存反射方式創(chuàng)建TestUser對(duì)象@Testpublic void testReflexWithCache() throws Exception { long start = System.currentTimeMillis();

 TestUser user = null;

 Class rUserClass = Class.forName("RefleDemo.TestUser"); int i = 0; while(i<1000000){

  ++i;

  user = (TestUser) rUserClass.newInstance();

 } long end = System.currentTimeMillis();

 System.out.println("通過(guò)緩存反射創(chuàng)建對(duì)象耗時(shí):"+(end - start ) + "ms");

}//通過(guò)緩存反射創(chuàng)建對(duì)象耗時(shí):41ms

其實(shí)通過(guò)代碼我們可以發(fā)現(xiàn),是Class.forName這個(gè)方法比較耗時(shí),它實(shí)際上調(diào)用了一個(gè)本地方法,通過(guò)這個(gè)方法來(lái)要求JVM查找并加載指定的類。所以我們?cè)陧?xiàng)目中使用的時(shí)候,可以把Class.forName返回的Class對(duì)象緩存起來(lái),下一次使用的時(shí)候直接從緩存里面獲取,這樣就極大的提高了獲取Class的效率。同理,在我們獲取Constructor、Method等對(duì)象的時(shí)候也可以緩存起來(lái)使用,避免每次使用時(shí)再來(lái)耗費(fèi)時(shí)間創(chuàng)建。

測(cè)試反射調(diào)用方法

@Testpublic void testReflexMethod() throws Exception { long start = System.currentTimeMillis();

 Class testUserClass = Class.forName("RefleDemo.TestUser");

 TestUser testUser = (TestUser) testUserClass.newInstance();

 Method method = testUserClass.getMethod("sayHi"); int i = 0; while(i<100000000){

  ++i;

  method.invoke(testUser);

 } long end = System.currentTimeMillis();

 System.out.println("反射調(diào)用方法耗時(shí):"+(end - start ) + "ms");

}//反射調(diào)用方法耗時(shí):330ms
@Testpublic void testReflexMethod() throws Exception { long start = System.currentTimeMillis();

 Class testUserClass = Class.forName("RefleDemo.TestUser");

 TestUser testUser = (TestUser) testUserClass.newInstance();

 Method method = testUserClass.getMethod("sayHi"); int i = 0; while(i<100000000){

  ++i;

  method.setAccessible(true);

  method.invoke(testUser);

 } long end = System.currentTimeMillis();

 System.out.println("setAccessible=true 反射調(diào)用方法耗時(shí):"+(end - start ) + "ms");

}//setAccessible=true 反射調(diào)用方法耗時(shí):188ms

這里我們反射調(diào)用sayHi方法1億次,在調(diào)用了method.setAccessible(true)后,發(fā)現(xiàn)快了將近一半。查看API可以了解到,jdk在設(shè)置獲取字段,調(diào)用方法的時(shí)候會(huì)執(zhí)行安全訪問(wèn)檢查,而此類操作會(huì)比較耗時(shí),所以通過(guò)setAccessible(true)的方式可以關(guān)閉安全檢查,從而提升反射效率。

極致的反射

除了上面的手段,還有沒有什么辦法可以更極致的使用反射呢?這里介紹一個(gè)高性能反射工具包ReflectASM。它是通過(guò)字節(jié)碼生成的方式來(lái)實(shí)現(xiàn)的反射機(jī)制,下面是一個(gè)跟java反射的性能比較。

結(jié)語(yǔ)

最后總結(jié)一下,為了更好的使用反射,我們應(yīng)該在項(xiàng)目啟動(dòng)的時(shí)候?qū)⒎瓷渌枰南嚓P(guān)配置及數(shù)據(jù)加載進(jìn)內(nèi)存中,在運(yùn)行階段都從緩存中取這些元數(shù)據(jù)進(jìn)行反射操作。大家也不用懼怕反射,虛擬機(jī)在不斷的優(yōu)化,只要我們方法用的對(duì),它并沒有”傳聞“中的那么慢,當(dāng)我們對(duì)性能有極致追求的時(shí)候,可以考慮通過(guò)三方包,直接對(duì)字節(jié)碼進(jìn)行操作。

相關(guān)文章

  • PHP簡(jiǎn)單讀取xml文件的方法示例

    PHP簡(jiǎn)單讀取xml文件的方法示例

    這篇文章主要介紹了PHP簡(jiǎn)單讀取xml文件的方法,涉及php針對(duì)xml文件節(jié)點(diǎn)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-04-04
  • PHP下載文件函數(shù)與用法示例

    PHP下載文件函數(shù)與用法示例

    這篇文章主要介紹了PHP下載文件函數(shù)與用法,結(jié)合實(shí)例形式分析了php文件下載相關(guān)函數(shù)、實(shí)現(xiàn)方法與操作技巧,需要的朋友可以參考下
    2019-09-09
  • php鏈?zhǔn)讲僮鱩ysql數(shù)據(jù)庫(kù)(封裝類帶使用示例)

    php鏈?zhǔn)讲僮鱩ysql數(shù)據(jù)庫(kù)(封裝類帶使用示例)

    本文代碼將一些簡(jiǎn)單常用的SQL語(yǔ)句,拆分、封裝成鏈?zhǔn)胶瘮?shù)與終結(jié)函數(shù),鏈?zhǔn)讲僮鳑]有先后之分,實(shí)現(xiàn)傻瓜式mysql數(shù)據(jù)庫(kù)操作。?同時(shí)學(xué)習(xí)下靜態(tài)成員函數(shù),實(shí)現(xiàn)鏈?zhǔn)讲僮鞯木唧w語(yǔ)法。
    2023-02-02
  • php下統(tǒng)計(jì)用戶在線時(shí)間的一種嘗試

    php下統(tǒng)計(jì)用戶在線時(shí)間的一種嘗試

    一直以來(lái),在web開發(fā)中,準(zhǔn)確統(tǒng)計(jì)用戶在線時(shí)間都是一個(gè)老大難的問(wèn)題,雖然已經(jīng)有很多人去嘗試各種不同的方案,可是畢竟項(xiàng)目不同,所用到的方法也是千差萬(wàn)別
    2010-08-08
  • PHP實(shí)現(xiàn)實(shí)時(shí)生成并下載超大數(shù)據(jù)量的EXCEL文件詳解

    PHP實(shí)現(xiàn)實(shí)時(shí)生成并下載超大數(shù)據(jù)量的EXCEL文件詳解

    EXCEL文件的處理是我們?cè)谌粘9ぷ髦薪?jīng)常會(huì)遇到的,這篇文章主要給大家介紹了關(guān)于利用PHP如何實(shí)現(xiàn)實(shí)時(shí)生成并下載超大數(shù)據(jù)量的EXCEL文件,通過(guò)文中介紹的這個(gè)方法對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-10-10
  • php生成圖片驗(yàn)證碼的方法

    php生成圖片驗(yàn)證碼的方法

    驗(yàn)證碼是一種安全保護(hù)機(jī)制,在注冊(cè)時(shí)要求必須有人工操作進(jìn)行驗(yàn)證,圖片驗(yàn)證碼的實(shí)現(xiàn)十分簡(jiǎn)單,感興趣的小伙伴們可以參考一下
    2016-04-04
  • PHP讀取數(shù)據(jù)庫(kù)并按照中文名稱進(jìn)行排序?qū)崿F(xiàn)代碼

    PHP讀取數(shù)據(jù)庫(kù)并按照中文名稱進(jìn)行排序?qū)崿F(xiàn)代碼

    有時(shí)候我們讀取數(shù)據(jù)庫(kù)輸出的時(shí)候可能會(huì)需要按照中文用戶名的方式進(jìn)行排序,有些新手朋友對(duì)此事無(wú)從下手,接下來(lái)由小編為您詳細(xì)介紹實(shí)現(xiàn)方法,感興趣的朋友可以了解下啊
    2013-01-01
  • 數(shù)據(jù)結(jié)構(gòu)之利用PHP實(shí)現(xiàn)二分搜索樹

    數(shù)據(jù)結(jié)構(gòu)之利用PHP實(shí)現(xiàn)二分搜索樹

    這篇文章主要給大家介紹了關(guān)于數(shù)據(jù)結(jié)構(gòu)之利用PHP實(shí)現(xiàn)二分搜索樹的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • php結(jié)合mysql與mysqli擴(kuò)展處理事務(wù)的方法

    php結(jié)合mysql與mysqli擴(kuò)展處理事務(wù)的方法

    這篇文章主要介紹了php結(jié)合mysql與mysqli擴(kuò)展處理事務(wù)的方法,結(jié)合實(shí)例形式分析了php使用mysql與mysqli處理事務(wù)的相關(guān)技巧與注意事項(xiàng),需要的朋友可以參考下
    2016-06-06
  • php skymvc 一款輕量、簡(jiǎn)單的php

    php skymvc 一款輕量、簡(jiǎn)單的php

    skymvc是一款輕量、簡(jiǎn)單的php mvc框架,借鑒了各大框架的設(shè)計(jì),采納了很多優(yōu)秀的函數(shù)及類,skymvc不鼓勵(lì)傻瓜式的開發(fā),更注重給予開發(fā)者更多的思考空間。
    2011-06-06

最新評(píng)論

都兰县| 江北区| 惠东县| 平凉市| 沙河市| 二连浩特市| 泸定县| 色达县| 三穗县| 陈巴尔虎旗| 通化市| 东阿县| 襄樊市| 安顺市| 方正县| 怀宁县| 洪泽县| 长顺县| 通州市| 新田县| 青海省| 横山县| 星座| 文山县| 赤壁市| 密云县| 双鸭山市| 金川县| 和顺县| 巴里| 东丽区| 泗阳县| 讷河市| 泊头市| 洛浦县| 堆龙德庆县| 晋州市| 溧阳市| 库尔勒市| 疏附县| 新乐市|