Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android 內部類的優化

android 內部類的優化

編輯:關於Android編程

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          : ''
      type          : '(LOne;)V'
      access        : 0x10002 (PRIVATE CONSTRUCTOR)
      code          -
      registers     : 2
      ins           : 2
      outs          : 1
      insns size    : 6 16-bit code units
0001a0:                                        |[0001a0] One.B.:(LOne;)V
0001b0: 5b01 0000                              |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // field@0000
0001b4: 7010 0400 0000                         |0002: invoke-direct {v0}, Ljava/lang/Object;.:()V // method@0004
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 units
0001bc:                                        |[0001bc] One.B.getA:()I
0001cc: 5410 0000                              |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // field@0000
0001d0: 7110 0300 0000                         |0002: invoke-static {v0}, LOne;.access$0:(LOne;)I // method@0003
0001d6: 0a00                                   |0005: move-result v0
0001d8: 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          : ''
      type          : '()V'
      access        : 0x10001 (PUBLIC CONSTRUCTOR)
      code          -
      registers     : 1
      ins           : 1
      outs          : 1
      insns size    : 4 16-bit code units
0001dc:                                        |[0001dc] One.:()V
0001ec: 7010 0400 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.:()V // method@0004
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 units
0001f4:                                        |[0001f4] One.access$0:(LOne;)I
000204: 5210 0100                              |0000: iget v0, v1, LOne;.a:I // field@0001
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          : ''
      type          : '(LOne;)V'
      access        : 0x10000 (CONSTRUCTOR)
      code          -
      registers     : 2
      ins           : 2
      outs          : 1
      insns size    : 6 16-bit code units
0001a0:                                        |[0001a0] One.B.:(LOne;)V
0001b0: 5b01 0000                              |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // field@0000
0001b4: 7010 0400 0000                         |0002: invoke-direct {v0}, Ljava/lang/Object;.:()V // method@0004
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 units
0001bc:                                        |[0001bc] One.B.getA:()I
0001cc: 5410 0000                              |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // field@0000
0001d0: 7110 0300 0000                         |0002: invoke-static {v0}, LOne;.access$0:(LOne;)I // method@0003
0001d6: 0a00                                   |0005: move-result v0
0001d8: 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          : ''
      type          : '()V'
      access        : 0x10001 (PUBLIC CONSTRUCTOR)
      code          -
      registers     : 1
      ins           : 1
      outs          : 1
      insns size    : 4 16-bit code units
0001dc:                                        |[0001dc] One.:()V
0001ec: 7010 0400 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.:()V // method@0004
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 units
0001f4:                                        |[0001f4] One.access$0:(LOne;)I
000204: 5210 0100                              |0000: iget v0, v1, LOne;.a:I // field@0001
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          : ''
      type          : '(LOne;)V'
      access        : 0x10000 (CONSTRUCTOR)
      code          -
      registers     : 2
      ins           : 2
      outs          : 1
      insns size    : 6 16-bit code units
000184:                                        |[000184] One.B.:(LOne;)V
000194: 5b01 0000                              |0000: iput-object v1, v0, LOne$B;.this$0:LOne; // field@0000
000198: 7010 0300 0000                         |0002: invoke-direct {v0}, Ljava/lang/Object;.:()V // method@0003
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 units
0001a0:                                        |[0001a0] One.B.getA:()I
0001b0: 5410 0000                              |0000: iget-object v0, v1, LOne$B;.this$0:LOne; // field@0000
0001b4: 5200 0100                              |0002: iget v0, v0, LOne;.a:I // field@0001
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          : ''
      type          : '()V'
      access        : 0x10001 (PUBLIC CONSTRUCTOR)
      code          -
      registers     : 1
      ins           : 1
      outs          : 1
      insns size    : 4 16-bit code units
0001bc:                                        |[0001bc] One.:()V
0001cc: 7010 0300 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.:()V // method@0003
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)

已經沒有附加的方法了。

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

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

封裝。


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved