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 units
0001a0: |[0001a0] One.B.<init>:(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;.<init>:()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 : '<init>'
type : '()V'
access : 0x10001 (PUBLIC CONSTRUCTOR)
code -
registers : 1
ins : 1
outs : 1
insns size : 4 16-bit code units
0001dc: |[0001dc] One.<init>:()V
0001ec: 7010 0400 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()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 : '<init>'
type : '(LOne;)V'
access : 0x10000 (CONSTRUCTOR)
code -
registers : 2
ins : 2
outs : 1
insns size : 6 16-bit code units
0001a0: |[0001a0] One.B.<init>:(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;.<init>:()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 : '<init>'
type : '()V'
access : 0x10001 (PUBLIC CONSTRUCTOR)
code -
registers : 1
ins : 1
outs : 1
insns size : 4 16-bit code units
0001dc: |[0001dc] One.<init>:()V
0001ec: 7010 0400 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()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 : '<init>'
type : '(LOne;)V'
access : 0x10000 (CONSTRUCTOR)
code -
registers : 2
ins : 2
outs : 1
insns size : 6 16-bit code units
000184: |[000184] One.B.<init>:(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;.<init>:()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 : '<init>'
type : '()V'
access : 0x10001 (PUBLIC CONSTRUCTOR)
code -
registers : 1
ins : 1
outs : 1
insns size : 4 16-bit code units
0001bc: |[0001bc] One.<init>:()V
0001cc: 7010 0300 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()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)

已经没有附加的方法了。

假设外部类的成员是包訪问的,内部类是私有的相同也不会产生附加的方法。

内部类对外部类成员的訪问是不能直接訪问私有成员的,编译器会添加额外的辅助方法,避免的方法是改动外部类的成员为包訪问,文档中也提到了这会在一定程度上破坏

封装。

android 内部类的优化的更多相关文章

  1. Android应用性能优化(转)

    人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然连贯(帧率为24fps),用手机当然也需要感知屏幕操作的连贯性(尤其是动画过度),所以Android索性就把达到这 ...

  2. 包建强的培训课程(9):Android App性能优化

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  3. Android代码内存优化建议-Android官方篇

    转自:http://androidperformance.com/ http://developer.android.com/intl/zh-cn/training/displaying-bitmap ...

  4. Android开发性能优化总结(一)

    安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户. 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流. ...

  5. fir.im Weekly - 如何进行 Android App 性能优化

    关于 Android App 的优化,@anly-jun 用 3 个月完成了这一系列文章,从 性能分析工具 到 ANR .Layout .消除卡顿 到 内存优化.内存分析工具大概十五六篇,并对此做一个 ...

  6. Android客户端性能优化(魅族资深工程师毫无保留奉献)

    本文由魅族科技有限公司资深Android开发工程师degao(嵌入式企鹅圈原创团队成员)撰写,是degao在嵌入式企鹅圈发表的第一篇原创文章,毫无保留地总结分享其在领导魅族多个项目开发中的Androi ...

  7. Android UI性能优化实战, 识别View中的性能问题

    出自:[张鸿洋的博客]来源:http://blog.csdn.net/lmj623565791/article/details/45556391 1.概述 2015年初google发布了Android ...

  8. 转 iOS和android游戏纹理优化和内存优化(cocos2d-x)

    iOS和android游戏纹理优化和内存优化(cocos2d-x) (未完成) 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x不同平台读取纹理的机制不同.ios下面使用CGImage, ...

  9. android app性能优化大汇总(内存性能优化)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...

随机推荐

  1. hdu5829

    多校训练8,有官方题解 主要之前没写过ntt,感觉不是很懂原根 先贴一份当模板吧 #include<iostream> #include<cstdio> #include< ...

  2. easyui中导航菜单accordion与tree的动态添加

    博客分类: Java Web开发   Js代码   $.parser.parse(); $.ajax({ url:my.bp()+'/main/menuaction!createMenu.action ...

  3. 潜伏者(noip09年t1)解题报告 C++

    题目描述 R 国和 S 国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动.历尽艰险后,潜伏于 S 国的 R 国间谍小 C 终于摸清了 S 国军用密码的编码规则: 1. S 国军方内部欲发送的原 ...

  4. (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest

    layout: post title: (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest author: "luow ...

  5. dutacm.club 1094: 等差区间(RMQ区间最大、最小值,区间GCD)

    1094: 等差区间 Time Limit:5000/3000 MS (Java/Others)   Memory Limit:163840/131072 KB (Java/Others)Total ...

  6. 对Array.prototype.slice.call()方法的理解在看别人代码时,发现有这么个写法:[].slice.call(arguments, 0),这到底是什么意思呢?

    1.基础 1)slice() 方法可从已有的数组中返回选定的元素. start:必需.规定从何处开始选取.如果是负数,那么它规定从数组尾部开始算起的位置.也就是说,-1 指最后一个元素,-2 指倒数第 ...

  7. JAVA net 笔记

    1.InetAddress 获取主机ip等 2.URL 3.URLConnection (url.openConnection() 创建对象) 4.BufferedReader 5.InputStre ...

  8. Servlet规范简介

    引言 Web 框架一般是通过一个 Servlet 提供统一的请求入口,将指定的资源映射到这个 servlet, 在这个 servlet 中进行框架的初始化配置,访问 Web 页面中的数据,进行逻辑处理 ...

  9. CodeForces - 981E Addition on Segments

    考虑每个点i在什么情况下会成为最大值. 当选的区间子集是 包含i的区间的一个子集的时候,i肯定会是最大值. 所以我们就可以用这种方法得到所有点的可能的最大值是多少... 也就是说,最后的局面可以仅由一 ...

  10. 【摘】请问make -j8 和make -j4 是什么意思?什么作用?

    看到别人写的Shell脚本中有 make -j8 等字眼,Google了一下,网友说是: make linux kernel/rootfs时候多线程执行.