android 內部類的最佳化

來源:互聯網
上載者:User

標籤:des   android   blog   class   code   c   


developer.android.com 文檔中有一篇關於效能的文章,裡面提到了內部類的使用。文章建議“對於私人內部類 使用 包存取權限代替私人許可權訪問”,

這裡說的是在內部類訪問外部類的成員或方法時如果 內部類是私人的並且外部類的成員也是私人的,那麼編譯器就會為內部類在外部類中增加一個靜態方法。

真的是這樣的嗎?只有試一試才知道。

我們使用一個簡單的例子來測試下:

public class One {private int a;private class B{public int getA(){return a;}}}

上邊的代碼為One建立了一個私人的內部類B,並且B中有一個方法訪問到了 One中的私人成員 a。我們把上邊的代碼編譯成 dex檔案後匯出程式的指令碼與類資訊。

匯出的結果如下:

Processing ‘one.dex‘...Opened ‘one.dex‘, DEX version ‘035‘Class #0            -  Class descriptor  : ‘LOne$B;‘  Access flags      : 0x0000 ()  Superclass        : ‘Ljava/lang/Object;‘  Interfaces        -  Static fields     -  Instance fields   -    #0              : (in LOne$B;)      name          : ‘this$0‘      type          : ‘LOne;‘      access        : 0x1010 (FINAL SYNTHETIC)  Direct methods    -    #0              : (in LOne$B;)      name          : ‘<init>‘      type          : ‘(LOne;)V‘      access        : 0x10002 (PRIVATE CONSTRUCTOR)      code          -      registers     : 2      ins           : 2      outs          : 1      insns size    : 6 16-bit code units0001a0:                                        |[0001a0] One.B.<init>:(LOne;)V0001b0: 5b01 0000                              |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // [email protected]0001b4: 7010 0400 0000                         |0002: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // [email protected]0001ba: 0e00                                   |0005: return-void      catches       : (none)      positions     :         0x0000 line=7      locals        :         0x0000 - 0x0006 reg=0 this LOne$B;   Virtual methods   -    #0              : (in LOne$B;)      name          : ‘getA‘      type          : ‘()I‘      access        : 0x0001 (PUBLIC)      code          -      registers     : 2      ins           : 1      outs          : 1      insns size    : 7 16-bit code units0001bc:                                        |[0001bc] One.B.getA:()I0001cc: 5410 0000                              |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // [email protected]0001d0: 7110 0300 0000                         |0002: invoke-static {v0}, LOne;.access$0:(LOne;)I // [email protected]0001d6: 0a00                                   |0005: move-result v00001d8: 0f00                                   |0006: return v0      catches       : (none)      positions     :         0x0000 line=10      locals        :         0x0000 - 0x0007 reg=1 this LOne$B;   source_file_idx   : 10 (One.java)Class #1            -  Class descriptor  : ‘LOne;‘  Access flags      : 0x0001 (PUBLIC)  Superclass        : ‘Ljava/lang/Object;‘  Interfaces        -  Static fields     -  Instance fields   -    #0              : (in LOne;)      name          : ‘a‘      type          : ‘I‘      access        : 0x0002 (PRIVATE)  Direct methods    -    #0              : (in LOne;)      name          : ‘<init>‘      type          : ‘()V‘      access        : 0x10001 (PUBLIC CONSTRUCTOR)      code          -      registers     : 1      ins           : 1      outs          : 1      insns size    : 4 16-bit code units0001dc:                                        |[0001dc] One.<init>:()V0001ec: 7010 0400 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // [email protected]0001f2: 0e00                                   |0003: return-void      catches       : (none)      positions     :         0x0000 line=3      locals        :         0x0000 - 0x0004 reg=0 this LOne;     #1              : (in LOne;)      name          : ‘access$0‘      type          : ‘(LOne;)I‘      access        : 0x1008 (STATIC SYNTHETIC)      code          -      registers     : 2      ins           : 1      outs          : 0      insns size    : 3 16-bit code units0001f4:                                        |[0001f4] One.access$0:(LOne;)I000204: 5210 0100                              |0000: iget v0, v1, LOne;.a:I // [email protected]000208: 0f00                                   |0002: return v0      catches       : (none)      positions     :         0x0000 line=5      locals        :   Virtual methods   -  source_file_idx   : 10 (One.java)

哈看到沒 One中多一個方法,而我們的源碼中是沒有的。
One.access$0:(LOne;)I

現在我們把源碼改下

public class One {private int a;class B{public int getA(){return a;}}}

然後在編譯,匯出:

Processing ‘one.dex‘...Opened ‘one.dex‘, DEX version ‘035‘Class #0            -  Class descriptor  : ‘LOne$B;‘  Access flags      : 0x0000 ()  Superclass        : ‘Ljava/lang/Object;‘  Interfaces        -  Static fields     -  Instance fields   -    #0              : (in LOne$B;)      name          : ‘this$0‘      type          : ‘LOne;‘      access        : 0x1010 (FINAL SYNTHETIC)  Direct methods    -    #0              : (in LOne$B;)      name          : ‘<init>‘      type          : ‘(LOne;)V‘      access        : 0x10000 (CONSTRUCTOR)      code          -      registers     : 2      ins           : 2      outs          : 1      insns size    : 6 16-bit code units0001a0:                                        |[0001a0] One.B.<init>:(LOne;)V0001b0: 5b01 0000                              |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // [email protected]0001b4: 7010 0400 0000                         |0002: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // [email protected]0001ba: 0e00                                   |0005: return-void      catches       : (none)      positions     :         0x0000 line=7      locals        :         0x0000 - 0x0006 reg=0 this LOne$B;   Virtual methods   -    #0              : (in LOne$B;)      name          : ‘getA‘      type          : ‘()I‘      access        : 0x0001 (PUBLIC)      code          -      registers     : 2      ins           : 1      outs          : 1      insns size    : 7 16-bit code units0001bc:                                        |[0001bc] One.B.getA:()I0001cc: 5410 0000                              |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // [email protected]0001d0: 7110 0300 0000                         |0002: invoke-static {v0}, LOne;.access$0:(LOne;)I // [email protected]0001d6: 0a00                                   |0005: move-result v00001d8: 0f00                                   |0006: return v0      catches       : (none)      positions     :         0x0000 line=10      locals        :         0x0000 - 0x0007 reg=1 this LOne$B;   source_file_idx   : 10 (One.java)Class #1            -  Class descriptor  : ‘LOne;‘  Access flags      : 0x0001 (PUBLIC)  Superclass        : ‘Ljava/lang/Object;‘  Interfaces        -  Static fields     -  Instance fields   -    #0              : (in LOne;)      name          : ‘a‘      type          : ‘I‘      access        : 0x0002 (PRIVATE)  Direct methods    -    #0              : (in LOne;)      name          : ‘<init>‘      type          : ‘()V‘      access        : 0x10001 (PUBLIC CONSTRUCTOR)      code          -      registers     : 1      ins           : 1      outs          : 1      insns size    : 4 16-bit code units0001dc:                                        |[0001dc] One.<init>:()V0001ec: 7010 0400 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // [email protected]0001f2: 0e00                                   |0003: return-void      catches       : (none)      positions     :         0x0000 line=3      locals        :         0x0000 - 0x0004 reg=0 this LOne;     #1              : (in LOne;)      name          : ‘access$0‘      type          : ‘(LOne;)I‘      access        : 0x1008 (STATIC SYNTHETIC)      code          -      registers     : 2      ins           : 1      outs          : 0      insns size    : 3 16-bit code units0001f4:                                        |[0001f4] One.access$0:(LOne;)I000204: 5210 0100                              |0000: iget v0, v1, LOne;.a:I // [email protected]000208: 0f00                                   |0002: return v0      catches       : (none)      positions     :         0x0000 line=5      locals        :   Virtual methods   -  source_file_idx   : 10 (One.java)
依然有附加的方法
One.access$0:(LOne;)I


我們在修改下

public class One {int a;class B{public int getA(){return a;}}}

在編譯 匯出

Processing ‘one.dex‘...Opened ‘one.dex‘, DEX version ‘035‘Class #0            -  Class descriptor  : ‘LOne$B;‘  Access flags      : 0x0000 ()  Superclass        : ‘Ljava/lang/Object;‘  Interfaces        -  Static fields     -  Instance fields   -    #0              : (in LOne$B;)      name          : ‘this$0‘      type          : ‘LOne;‘      access        : 0x1010 (FINAL SYNTHETIC)  Direct methods    -    #0              : (in LOne$B;)      name          : ‘<init>‘      type          : ‘(LOne;)V‘      access        : 0x10000 (CONSTRUCTOR)      code          -      registers     : 2      ins           : 2      outs          : 1      insns size    : 6 16-bit code units000184:                                        |[000184] One.B.<init>:(LOne;)V000194: 5b01 0000                              |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // [email protected]000198: 7010 0300 0000                         |0002: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // [email protected]00019e: 0e00                                   |0005: return-void      catches       : (none)      positions     :         0x0000 line=7      locals        :         0x0000 - 0x0006 reg=0 this LOne$B;   Virtual methods   -    #0              : (in LOne$B;)      name          : ‘getA‘      type          : ‘()I‘      access        : 0x0001 (PUBLIC)      code          -      registers     : 2      ins           : 1      outs          : 0      insns size    : 5 16-bit code units0001a0:                                        |[0001a0] One.B.getA:()I0001b0: 5410 0000                              |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // [email protected]0001b4: 5200 0100                              |0002: iget v0, v0, LOne;.a:I // [email protected]0001b8: 0f00                                   |0004: return v0      catches       : (none)      positions     :         0x0000 line=10      locals        :         0x0000 - 0x0005 reg=1 this LOne$B;   source_file_idx   : 9 (One.java)Class #1            -  Class descriptor  : ‘LOne;‘  Access flags      : 0x0001 (PUBLIC)  Superclass        : ‘Ljava/lang/Object;‘  Interfaces        -  Static fields     -  Instance fields   -    #0              : (in LOne;)      name          : ‘a‘      type          : ‘I‘      access        : 0x0000 ()  Direct methods    -    #0              : (in LOne;)      name          : ‘<init>‘      type          : ‘()V‘      access        : 0x10001 (PUBLIC CONSTRUCTOR)      code          -      registers     : 1      ins           : 1      outs          : 1      insns size    : 4 16-bit code units0001bc:                                        |[0001bc] One.<init>:()V0001cc: 7010 0300 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // [email protected]0001d2: 0e00                                   |0003: return-void      catches       : (none)      positions     :         0x0000 line=3      locals        :         0x0000 - 0x0004 reg=0 this LOne;   Virtual methods   -  source_file_idx   : 9 (One.java)

已經沒有附加的方法了。

如果外部類的成員是包訪問的,內部類是私人的同樣也不會產生附加的方法。

內部類對外部類成員的訪問是不能直接存取私人成員的,編譯器會增加額外的輔助方法,避免的方法是修改外部類的成員為包訪問,文檔中也提到了這會在一定程度上破壞

封裝。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.