08.Java反射問題

目錄介紹

  • 8.0.0.1 反射的原理是什么?有哪些途徑獲取到Class對(duì)象督怜,Class類的含義和作用是什么眶掌?什么是class類?
  • 8.0.0.2 有哪些方式可以提高反射效率绒瘦?為何反射消耗性能称簿?究竟是怎么影響的,舉例說明惰帽?
  • 8.0.0.3 java反射機(jī)制提供了什么功能憨降?發(fā)射具有暴力訪問權(quán)限,如何防止反射序列化攻擊單例该酗?
  • 8.0.0.4 通過反射獲得泛型的實(shí)際類型參數(shù)券册?反射獲取構(gòu)造方法,變量垂涯,方法的方法是哪些?
  • 8.0.0.5 getGenericParameterTypes 與 getParameterTypes區(qū)別航邢?
  • 8.0.0.6 反射有什么作用和應(yīng)用耕赘?反射和注解相比,為何反射消耗性能膳殷,有什么優(yōu)缺點(diǎn)操骡?

好消息

  • 博客筆記大匯總【15年10月到至今】,包括Java基礎(chǔ)及深入知識(shí)點(diǎn)赚窃,Android技術(shù)博客册招,Python學(xué)習(xí)筆記等等,還包括平時(shí)開發(fā)中遇到的bug匯總勒极,當(dāng)然也在工作之余收集了大量的面試題是掰,長期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的辱匿!同時(shí)也開源了生活博客键痛,從12年起,積累共計(jì)500篇[近100萬字]匾七,將會(huì)陸續(xù)發(fā)表到網(wǎng)上絮短,轉(zhuǎn)載請(qǐng)注明出處,謝謝昨忆!
  • 鏈接地址:https://github.com/yangchong211/YCBlogs
  • 如果覺得好丁频,可以star一下,謝謝!當(dāng)然也歡迎提出建議席里,萬事起于忽微叔磷,量變引起質(zhì)變!所有博客將陸續(xù)開源到GitHub胁勺!

8.0.0.1 反射的原理是什么世澜?有哪些途徑獲取到Class對(duì)象,Class類的含義和作用是什么署穗?什么是class類续搀?

  • 反射的原理是什么?
    • 反射是為了能夠動(dòng)態(tài)的加載一個(gè)類惫霸,動(dòng)態(tài)的調(diào)用一個(gè)方法矮烹,動(dòng)態(tài)的訪問一個(gè)屬性等動(dòng)態(tài)要求而設(shè)計(jì)的。它的出發(fā)點(diǎn)就在于JVM會(huì)為每個(gè)類創(chuàng)建一個(gè)java.lang.Class類的實(shí)例褐啡,通過該對(duì)象可以獲取這個(gè)類的信息诺舔,然后通過使用java.lang.reflect包下得API以達(dá)到各種動(dòng)態(tài)需求。
    • 反射機(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ì)象的方法的功能稱為java語言的反射機(jī)制。
  • 有哪些途徑獲取到Class對(duì)象莉恼,Class類的含義和作用是什么拌喉?
    • 每一個(gè)Class類的對(duì)象就代表了一種被加載進(jìn)入JVM的類,它代表了該類的一種信息映射俐银。開發(fā)者可以通過3種途徑獲取到Class對(duì)象尿背。
    • 技術(shù)博客大總結(jié)
    • 第一種方式:Class的forName()方法的返回值就是Class類型,也就是動(dòng)態(tài)導(dǎo)入類的Class對(duì)象的引用捶惜。
    • public static Class<?> forName(String className) throws ClassNotFoundException
    • 第二種方式:每個(gè)類都會(huì)有一個(gè)名稱為Class的靜態(tài)屬性田藐,通過它也是可以獲取到Class對(duì)象的,示例代碼如下:
      Class<Student> clazz = Student.class;   // 訪問Student類的class屬性
      
    • 第三種方式:Object類中有一個(gè)名為getClass的成員方法吱七,它返回的是對(duì)象的運(yùn)行時(shí)類的Class對(duì)象坞淮。因?yàn)镺bject類是所有類的父類,所以陪捷,所有的對(duì)象都可以使用該方法得到它運(yùn)行時(shí)類的Class對(duì)象回窘,示例代碼如下:
      Student stu = new Student();
      Class<Student> clazz = stu.getClass();   // 調(diào)用Student對(duì)象的getName方法
      
  • 什么是class類?
    • .class文件:是由一個(gè).java文件通過編譯過程生成的.class文件市袖。Class對(duì)象:當(dāng)Java虛擬機(jī)加載一個(gè).class文件到內(nèi)存時(shí)啡直,都會(huì)生成一個(gè)對(duì)應(yīng)的Class對(duì)象烁涌,注意的是這個(gè)Class對(duì)象有且只有一個(gè)存在于內(nèi)存當(dāng)中。

8.0.0.2 有哪些方式可以提高反射效率酒觅?為何反射消耗性能撮执?究竟是怎么影響的,舉例說明舷丹?

  • 有哪些方式可以提高反射效率抒钱?
    • 善用API:比如,盡量不要getMethods()后再遍歷篩選颜凯,而直接用getMethod(methodName)來根據(jù)方法名獲取方法谋币。
    • 技術(shù)博客大總結(jié)
    • 適當(dāng)使用緩存:比如,需要多次動(dòng)態(tài)創(chuàng)建一個(gè)類的實(shí)例的時(shí)候症概,有緩存的寫法會(huì)比沒有緩存要快很多:
    // 1. 沒有緩存
    void createInstance(String className){
        return Class.forName(className).newInstance();
    }
    
    // 2. 緩存forName的結(jié)果
    void createInstance(String className){
        cachedClass = cache.get(className);
        if (cachedClass == null){
            cachedClass = Class.forName(className);
            cache.set(className, cachedClass);
        }
        return cachedClass.newInstance();
    }
    
  • 為何反射消耗性能蕾额?

8.0.0.3 java反射機(jī)制提供了什么功能?發(fā)射具有暴力訪問權(quán)限彼城,如何避免反射攻擊诅蝶?

  • java反射機(jī)制提供了什么功能?
    • 在運(yùn)行時(shí)能夠判斷任意一個(gè)對(duì)象所屬的類
    • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象
    • 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法
    • 在運(yùn)行時(shí)調(diào)用任一對(duì)象的方法技術(shù)博客大總結(jié)
    • 在運(yùn)行時(shí)創(chuàng)建新類對(duì)象
  • 發(fā)射具有暴力訪問權(quán)限募壕,如何避免反射攻擊调炬?
  • 如何防止反射序列化攻擊單例
    • 枚舉單例
      public enum Singleton {
          INSTANCE {
              @Override
              protected void read() {
                  System.out.println("read");
              }
              @Override
              protected void write() {
                  System.out.println("write");
              }
          };
          protected abstract void read();
          protected abstract void write();
      }
      
    • class文件:
      public abstract class Singleton extends Enum{
          private Singleton(String s, int i){
              super(s, i);
          }
      
          protected abstract void read();
          protected abstract void write();
          public static Singleton[] values(){
              Singleton asingleton[];
              int i;
              Singleton asingleton1[];
              System.arraycopy(asingleton = ENUM$VALUES, 0, asingleton1 = new Singleton[i = asingleton.length], 0, i);
              return asingleton1;
          }
      
          public static Singleton valueOf(String s) {
              return (Singleton)Enum.valueOf(singleton/Singleton, s);
          }
      
          Singleton(String s, int i, Singleton singleton){
              this(s, i);
          }
      
          public static final Singleton INSTANCE;
          private static final Singleton ENUM$VALUES[];
      
          static {
              INSTANCE = new Singleton("INSTANCE", 0){
      
                  protected void read(){
                      System.out.println("read");
                  }
      
                  protected void write(){
                      System.out.println("write");
                  }
      
              };
              ENUM$VALUES = (new Singleton[] {
                  INSTANCE
              });
          }
      }
      
      • 類的修飾abstract,所以沒法實(shí)例化舱馅,反射也無能為力筐眷。關(guān)于線程安全的保證,其實(shí)是通過類加載機(jī)制來保證的习柠,我們看看INSTANCE的實(shí)例化時(shí)機(jī),是在static塊中照棋,JVM加載類的過程顯然是線程安全的资溃。對(duì)于防止反序列化生成新實(shí)例的問題還不是很明白,一般的方法我們會(huì)在該類中添加上如下方法烈炭,不過枚舉中也沒有顯示的寫明該方法溶锭。技術(shù)博客大總結(jié)
      //readResolve to prevent another instance of Singleton
      private Object readResolve(){
          return INSTANCE;
      }
      

8.0.0.4 通過反射獲得泛型的實(shí)際類型參數(shù)?反射獲取構(gòu)造方法符隙,變量趴捅,方法的方法是哪些?

  • 通過反射獲得泛型的實(shí)際類型參數(shù)
    • 把泛型變量當(dāng)成方法的參數(shù)霹疫,利用Method類的getGenericParameterTypes方法來獲取泛型的實(shí)際類型參數(shù)
    • 例子:
      public class GenericTest {
      
          public static void main(String[] args) throws Exception {
              getParamType();
          }
          
           /*利用反射獲取方法參數(shù)的實(shí)際參數(shù)類型*/
          public static void getParamType() throws NoSuchMethodException{
              Method method = GenericTest.class.getMethod("applyMap",Map.class);
              //獲取方法的泛型參數(shù)的類型
              Type[] types = method.getGenericParameterTypes();
              System.out.println(types[0]);
              //參數(shù)化的類型
              ParameterizedType pType  = (ParameterizedType)types[0];
              //原始類型
              System.out.println(pType.getRawType());
              //實(shí)際類型參數(shù)
              System.out.println(pType.getActualTypeArguments()[0]);
              System.out.println(pType.getActualTypeArguments()[1]);
          }
      
          /*供測試參數(shù)類型的方法*/
          public static void applyMap(Map<Integer,String> map){
      
          }
      
      }
      
    • 輸出結(jié)果:
      java.util.Map<java.lang.Integer, java.lang.String>
      interface java.util.Map
      class java.lang.Integer
      class java.lang.String
      
  • 反射獲取構(gòu)造方法拱绑,變量,方法的方法是哪些丽蝎?技術(shù)博客大總結(jié)
    • 在反射包中猎拨,我們常用的類主要有Constructor類表示的是Class 對(duì)象所表示的類的構(gòu)造方法,利用它可以在運(yùn)行時(shí)動(dòng)態(tài)創(chuàng)建對(duì)象、Field表示Class對(duì)象所表示的類的成員變量红省,通過它可以在運(yùn)行時(shí)動(dòng)態(tài)修改成員變量的屬性值(包含private)额各、Method表示Class對(duì)象所表示的類的成員方法,通過它可以動(dòng)態(tài)調(diào)用對(duì)象的方法(包含private)吧恃。

8.0.0.5 getGenericParameterTypes 與 getParameterTypes區(qū)別虾啦?

  • getGenericParameterTypes 與 getParameterTypes區(qū)別?
    • getGenericParameterTypes 與 getParameterTypes 都是獲取構(gòu)成函數(shù)的參數(shù)類型
    • 前者返回的是Type類型痕寓,后者返回的是Class類型傲醉,由于Type頂級(jí)接口,Class也實(shí)現(xiàn)了該接口厂抽,因此Class類是Type的子類需频,Type 表示的全部類型而每個(gè)Class對(duì)象表示一個(gè)具體類型的實(shí)例,如String.class僅代表String類型筷凤。由此看來Type與 Class 表示類型幾乎是相同的昭殉,只不過Type表示的范圍比Class要廣得多而已。當(dāng)然Type還有其他子類藐守,如:
      • TypeVariable:表示類型參數(shù)挪丢,可以有上界,比如:T extends Number
      • ParameterizedType:表示參數(shù)化的類型卢厂,有原始類型和具體的類型參數(shù)乾蓬,比如:List<String>
      • WildcardType:表示通配符類型,比如:?, ? extends Number, ? super Integer

8.0.0.6 反射有什么作用和應(yīng)用慎恒?反射和注解相比任内,為何反射消耗性能,有什么優(yōu)缺點(diǎn)融柬?

  • 反射有什么作用和應(yīng)用死嗦?
    • 含義:在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類都能知道它的所有屬性和方法粒氧,對(duì)于任何一個(gè)對(duì)象都能夠調(diào)用它的任何一個(gè)方法和屬性越除。
    • 功能:動(dòng)態(tài)性,體現(xiàn)在:在運(yùn)行時(shí)判斷任意一個(gè)類所具有的屬性和方法外盯; 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類摘盆;在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象;在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法饱苟;生成動(dòng)態(tài)代理
  • 為何反射消耗性能
  • 有什么優(yōu)缺點(diǎn)
    • 優(yōu)點(diǎn)
      • 動(dòng)態(tài)編譯:運(yùn)行時(shí)確定類型孩擂,綁定對(duì)象。動(dòng)態(tài)編譯最大限度的發(fā)揮了java的靈活性箱熬,體現(xiàn)了多態(tài)的應(yīng)用肋殴,有利于降低類之間的耦合性囤锉。
      • 反射機(jī)制的優(yōu)點(diǎn)就是可以實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建對(duì)象和編譯,體現(xiàn)出很大的靈活性护锤,特別是在開發(fā)中官地。它的靈活性就表現(xiàn)的十分明顯。比如烙懦,一個(gè)大型的軟件驱入,不可能一次就把把它設(shè)計(jì)的很完美,當(dāng)這個(gè)程序編譯后氯析,發(fā)布了亏较,當(dāng)發(fā)現(xiàn)需要更新某些功能時(shí),我們不可能要用戶把以前的卸載掩缓,再重新安裝新的版本雪情,假如這樣的話,這個(gè)軟件肯定是沒有多少人用的你辣。采用靜態(tài)的話巡通,需要把整個(gè)程序重新編譯一次才可以實(shí)現(xiàn)功能的更新,而采用反射機(jī)制的話舍哄,它就可以不用卸載宴凉,只需要在運(yùn)行時(shí)才動(dòng)態(tài)的創(chuàng)建和編譯,就可以實(shí)現(xiàn)該功能表悬。

其他介紹

01.關(guān)于博客匯總鏈接

02.關(guān)于我的博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蟆沫,隨后出現(xiàn)的幾起案子籽暇,更是在濱河造成了極大的恐慌,老刑警劉巖饭庞,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件戒悠,死亡現(xiàn)場離奇詭異,居然都是意外死亡但绕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門惶看,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捏顺,“玉大人,你說我怎么就攤上這事纬黎》荆” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵本今,是天一觀的道長拆座。 經(jīng)常有香客問我主巍,道長,這世上最難降的妖魔是什么挪凑? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任孕索,我火速辦了婚禮,結(jié)果婚禮上躏碳,老公的妹妹穿的比我還像新娘搞旭。我一直安慰自己,他們只是感情好菇绵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布肄渗。 她就那樣靜靜地躺著,像睡著了一般咬最。 火紅的嫁衣襯著肌膚如雪翎嫡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天永乌,我揣著相機(jī)與錄音惑申,去河邊找鬼。 笑死铆遭,一個(gè)胖子當(dāng)著我的面吹牛硝桩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枚荣,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼碗脊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了橄妆?” 一聲冷哼從身側(cè)響起衙伶,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎害碾,沒想到半個(gè)月后矢劲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慌随,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年芬沉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片阁猜。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丸逸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剃袍,到底是詐尸還是另有隱情黄刚,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布民效,位于F島的核電站憔维,受9級(jí)特大地震影響涛救,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜业扒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一检吆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧凶赁,春花似錦咧栗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咏窿,卻和暖如春斟或,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背集嵌。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工萝挤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人根欧。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓怜珍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親凤粗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酥泛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司嫌拣,掛了不少柔袁,但最終還是拿到小米、百度异逐、阿里捶索、京東、新浪灰瞻、CVTE腥例、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,253評(píng)論 11 349
  • 深入理解Class對(duì)象 RRTI的概念以及Class對(duì)象作用 認(rèn)識(shí)Class對(duì)象之前,先來了解一個(gè)概念酝润,RTTI(...
    架構(gòu)師springboot閱讀 1,565評(píng)論 0 3
  • 讀完《放眼看世界 一帶一路》燎竖,我感到熱血沸騰。這本書讓我看到了人類驚天動(dòng)地的創(chuàng)舉袍祖,看到了祖國現(xiàn)在與過去的...
    淵曠奚閱讀 271評(píng)論 0 3
  • 1 手機(jī)響了底瓣,“我今晚不回去了谢揪〗堵”接著“嘀嘀嘀......”捐凭。 目光吊在天花板上,枕著雙手一個(gè)鐘頭凳鬓,一點(diǎn)麻的感覺都...
    在風(fēng)閱讀 1,490評(píng)論 29 31
  • XML解析器 解析器類型:非驗(yàn)證解析器:檢查文檔格式是否良好驗(yàn)證解析器:使用DTD(Document Type D...
    lifeline張閱讀 216評(píng)論 0 1