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 : '<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 内部类的优化的更多相关文章
- Android应用性能优化(转)
人类大脑与眼睛对一个画面的连贯性感知其实是有一个界限的,譬如我们看电影会觉得画面很自然连贯(帧率为24fps),用手机当然也需要感知屏幕操作的连贯性(尤其是动画过度),所以Android索性就把达到这 ...
- 包建强的培训课程(9):Android App性能优化
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...
- Android代码内存优化建议-Android官方篇
转自:http://androidperformance.com/ http://developer.android.com/intl/zh-cn/training/displaying-bitmap ...
- Android开发性能优化总结(一)
安卓开发应用首先要讲究良好的用户体验,如果一款软件卡顿现象严重,不流畅,经常崩溃,那么将给用户带来极不良好的体验,从而损失用户. 在实际开发和学习中,我总结了一下关于安卓性能的优化,供大家参考交流. ...
- fir.im Weekly - 如何进行 Android App 性能优化
关于 Android App 的优化,@anly-jun 用 3 个月完成了这一系列文章,从 性能分析工具 到 ANR .Layout .消除卡顿 到 内存优化.内存分析工具大概十五六篇,并对此做一个 ...
- Android客户端性能优化(魅族资深工程师毫无保留奉献)
本文由魅族科技有限公司资深Android开发工程师degao(嵌入式企鹅圈原创团队成员)撰写,是degao在嵌入式企鹅圈发表的第一篇原创文章,毫无保留地总结分享其在领导魅族多个项目开发中的Androi ...
- Android UI性能优化实战, 识别View中的性能问题
出自:[张鸿洋的博客]来源:http://blog.csdn.net/lmj623565791/article/details/45556391 1.概述 2015年初google发布了Android ...
- 转 iOS和android游戏纹理优化和内存优化(cocos2d-x)
iOS和android游戏纹理优化和内存优化(cocos2d-x) (未完成) 1.2d游戏最占内存的无疑是图片资源. 2.cocos2d-x不同平台读取纹理的机制不同.ios下面使用CGImage, ...
- android app性能优化大汇总(内存性能优化)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...
随机推荐
- KO工作原理及带来的好处
介绍 Knockout是一个以数据模型(data model)为基础的能够帮助你创建富文本,响应显示和编辑用户界面的JavaScript类库.任何时候如果你的UI需要自动更新(比如:更新依赖于用户的行 ...
- (22)python 自动化
例子 from selenium import webdriver driver = webdriver.PhantomJS() driver.get("http://www.huhumh. ...
- (6)python 循环控制
一.if语句 1.条件执行和if语句 2.else子句 3.elif子句 多个检查条件时 4.嵌套代码 5.空语句 使用pass占位 6.断言 关键字 assert 判断表达式前加上这个关键字表示, ...
- POJ1751 Highways(Prim)
Highways Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 13182 Accepted: 3814 Speci ...
- POJ 3260 The Fewest Coins(背包问题)
[题目链接] http://poj.org/problem?id=3260 [题目大意] 给出你拥有的货币种类和每种的数量,商店拥有的货币数量是无限的, 问你买一个价值为m的物品,最少的货币流通数量为 ...
- 【最小割】【Dinic】bzoj3275 Number
每个点拆点,分别向源/汇连a[i]的边,满足条件的相互连INF的边,答案为sum-maxflow*2. 因为若有几个点不能同时被选,我们要贪心地选择其中和尽量大的部分,这可以由最小割来保证. #inc ...
- 【暴力】vijos P1897 学姐吃牛排
判断堆:递归判断每个节点的孩子是否都比其父亲大(小). 判断BST:中序遍历是否有序. #include<cstdio> using namespace std; #define lc ( ...
- ProgressDialog进度条对话框
(一) 1.效果图: 2.activity_main.xml <?xml version="1.0" encoding="utf-8"?> < ...
- Linux查找某个时间点后生成的文件(转)
需要找到某天(例如2017-04-13)以及这之后生成的空文件.那么这个要怎么处理呢?这个当然是用find命令来解决.如下所示, -mtime -5表示查找距现在5*24H内修改过的文件 -type ...
- ethtool 命令输出的注意点--网卡参数
http://blog.csdn.net/msdnchina/article/details/70339689