资源预览内容
第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
第9页 / 共9页
亲,该文档总共9页全部预览完了,如果喜欢就下载吧!
资源描述
Android 应用开发提高系列应用开发提高系列Practical Java 中文版中文版读书笔记读书笔记前言前言从开始学习 Android 到现在,囫囵吞枣学了许多控件、布局的使用方法和技巧,看了许多相关的文章,也积累了不少项目经验。藉此通过归纳、总结和梳理相关知识,扎实基础,进一步提高 Android 开发技能。学好 Android 需要扎实的 Java 功底,所以将本文作为系列文章的开篇。本系列文章面向有一定 Android 开发经验的读者,欢迎交流!书籍书籍Practical Java 中文版 03 版 侯捷、刘永丹译 本书和Effective Java,对前述重要而基础的技术细微处有着详尽、深刻、实用的介绍、剖析和范例,又以独立条款之姿展现,在内容的扎实度、可读性及易读性上的表现均十分良好。 本书围绕 Java 编程中遇到的实际问题展开。可以说书中所列专题正是那些令许多 Java 程序员困惑不已的 FAQ。作者擅长采用恰如其分的示例来阐释问题,以平时的语言娓娓道出中肯的建议。这些建议往往一语中的,能直接融入编程工作中,可见它们确实是出自作者从实践中获得的真知灼见。正文正文 注意:条目和用语可能与书籍有所出入,但尽量保持原样加一些自己的理解。一、一般技术一般技术 1. Java 唯一一种参数传递机制:by value(传值)。备注:当参数为对象时,以传值方式传递对象的引用。(个人理解:传递指针的拷贝) 2. 对不变的 data 和 object references 使用 final备注:当声明一个对象为 final 时,不能改变其指向,但能改变其对象的值。3. 缺省情况下所有非私有(non-private)、非静态(non-static)函数都可被覆写。3.1 如果函数不想被子类覆写,将函数声明为 final 即可。3.2 如果类不想被子类覆写,将函数声明为 final 即可,从而禁止覆写该类所有函数。还能提高性能。4. 在数组和 Vectors 之间慎重选择。数组数组VectorVector存储数据类型基本类型、引用类型引用类型元素默认值 YesNo自动改变大小固定不变动态增长速度快 YesNo备注: Vector 内部实际是以数组实现的。5. 多态优于 instanceof,必要时才使用 instanceof。备注:例如从父类转型为派生类时,需要使用 instanceof。6. 一旦不需要的对象引用,就将它设为 null。备注:如果局部变量的引用使用完离函数结束前还需要执行较大代码,可在使用完后设置为 null,以便或许能使其在垃圾回收器下次运行时被回收。二、 对象与相等性对象与相等性1. 区别 = 和 equals()备注:请使用 = 测试两个基本类型是否完全相同,或测试两个对象引用是否指向同一个对象;使用 equals()比较两个对象的内容是否相等。2. 不要依赖 equals()缺省实现备注:所有 Java 对象都隐含继承了 java.lang.Object,默认的 equals()只是检查对象引用是否指向同一个对象。3. 实现 equals()建议:3.1 请检查是否等于 this备注:测试是否指向同一个对象3.2 优先考虑使用 getClass()备注:getClass()返回某个对象的运行期类(runtime class)。确保只有相同 class 所产生的对象才有机会被视为相等。范例:public class Base Overridepublic boolean equals(Object obj) if(obj != null 3.3 调用 super.equals()唤起父类的相关行为备注:当你为一个派生类撰写 equals()时,你必须检查除 java.lang.Object 之外所有父类,看看它们是否都实现了equals()。如果有,那么一定要调用 super.equals()。3.4 在 equals()函数中谨慎使用 instanceof备注:如果允许派生类和父类进行比较,可能要采用 instanceof(getClass()会恒返回 false)。注意 instanceof类似于 is-a 语义,需要注意位置,即(子类 instanceof 父类 - 返回 true;反之为 false)。三、 异常处理异常处理1. 认识异常流程机制备注:try 区段 - catch 捕获区段可选 - finally 终结区段。2. 处理异常如果异常产生却未被捕获,发生异常的线程将中断。处理异常:a). 捕获并处理它,防止进一步传播。b). 捕获并抛出一个新的异常给调用端。备注:应确保新抛出的异常包含原异常相关信息,以保证不丢失重要信息。c). 不捕获,任其传播给调用端。输出错误信息:a). 日志文件记录曾经发生过的异常b). 输出异常输出到标准错误串流:如 e.printStackTrace()。3. 防止出现异常覆盖备注:如果在 catch 或 finally 区段又抛出了未捕获的异常,新的异常将覆盖 try 抛出的异常,只有一个异常可被传播到调用段。4. throws 子句备注:提供 throws 子句的用意在于,提醒函数调用者,告知可能发生的异常。编译器会强迫调用端捕捉这些被列出的异常,所以不要再开发周期的最后才添加。如果覆写对象(某个父类函数)没有抛出任何异常,那么覆写函数因为增加了代码而引发异常,那么你必须在新函数中捕捉异常并处理。5. 使用 finally 避免资源泄漏备注:finally 区段代码无论是否发生异常都将执行,尤其适合维护对象内部状态和清理 non-memory 资源。6. 使用建议:a). 不要从 try 区段执行 return、break 或 continue 语句离开 try 区段备注:如果 try 区段和 finally 区段都 return 数据,将返回 finally 区段 return 的数据。b). 将 try/catch 区段置于循环之外备注:异常对代码性能产生负面影响c). 不要将异常用于流程控制d). 在构造函数中抛出异常e). 抛出异常之前将对象恢复为有效状态备注:考虑下次执行这段代码时会发生什么事情,代码是否还能正常运行。结束结束预计本系列前几篇文章为Practical Java和Effective Java的读书笔记,后续内容还在规划当中,也欢迎大家把感兴趣的内容反馈给我作为潜在的系列文章。Android 应用开发提高系列(应用开发提高系列(2)Practical Java 中文版中文版读书笔记(下)读书笔记(下)正文正文 注意:条目和用语可能与书籍有所出入,但尽量保持原样加一些自己的理解。一、性能1. 先把焦点放在设计、数据结构和算法身上备注:良好的设计、明智的选择数据结构和算法可能比高效代码更重要。2. 不要依赖编译器优化技术3. 理解运行时(runtime)代码优化备注:JIT 将 bytecode 于运行时转换为本地二进制码,从而提高性能。因此编译后代码被执行次数越多,本机代码生成代价就很合算。4. 连接字符串使用 StringBuffer 要比 String 快,尤其是大量字符串拼接5. 将对象创建成本降至最小备注:复用既有对象,不要创建非必要的对象,只在需要的时候才创建它们。6. 将同步化(synchronization)降至最低备注:如果 synchronized 函数抛出异常,则在异常离开函数之前,锁会自动释放。如果整个函数都需要被同步化,为了产生体积较小且执行速度较快的代码,请优先使用函数修饰符,而不是在函数内使用 synchronized 代码块。7. 尽可能使用 stack 变量备注:如果在函数中频繁访问成员变量、静态变量,可以用本地(local)变量替代,最后操作完后再赋值给成员/静态变量。8. 尽可能的使用 static、final 和 private 函数备注:此类函数可以在编译期间被静态决议(statically resolved),而不需要动态议决(dynamic resolved)。(子类无法覆写)9. 类的成员变量、静态变量都有缺省值,务须重复初始化备注:记住,本地变量没有缺省值(例如函数内定义的变量)。10. 尽可能的使用基本数据类型备注:如 int、short、char、boolean,使得代码更快更小。11. 不要使用枚举器(Enumeration)和迭代器(Iterator)来遍历 Vector备注:使用 for 循环+get()12. 使用 System.arraycopy()来复制数组备注:使用 System.arraycopy()代替 for 循环,可以产生更快的代码。如:public void copyArray(int src, int dest) int size = src.length;System.arraycopy(src, 0, dest, 0, size);System.arraycopy()是以 native method 实现的,可以直接、高效的移动原始数组到目标数组,因此它执行速度更快。13. 优先使用数组,然后才考虑 Vector 和 ArrayList,理由:a). Vector 的 get()是同步的b). ArrayList 基本上就是一个非线程同步的 Vector,比 Vector 要快c). ArrayList 和 Vector 添加元素或移除元素都需要重新整理数组。备注:不要仅仅因为手上有个数不定的数据需要存储,就毫无选择的使用 Vector 或 ArrayList。可以考虑创建一个足够大的数组,通常这样可能会浪费内存,但性能上的收益可能超过内存方面的代价。14. 手工优化代码a). 剔除空白函数和无用代码b). 削减强度备注:以更高效的操作替换成本昂贵的操作。一个常见的优化手法是使用复式复制操作符(如+=、-=)。c). 合并常量备注:将变量声明为 final,使得操作在编译器就进行。d). 删减相同的子表达式备注:可用一个临时变量代替重复的表达式。e). 展开循环备注:如循环次数少且已知循环次数,可展开去掉循环结构,直接访问数组元素。缺点是会产生更多代码。f). 简化代数备注:使用数学技巧来简化表达式。(例如从 1+.+100 的问题)g). 搬移循环内的不变式备注:循环内不变化的表达式可用移至循环外,不必重复计算表达式。15. 编译为本机代码备注:将程序的某部分编译为本机二进制代码,然后通过 JNI 访问。二、多线程1. 对于实例(instance)函数,同步机制锁定的是对象,而不是函数和代码块。备注:函数或代码块被声明为 synchronized 并非意味它在同一时刻只能有一个线程执行(同一对象不同线程调用会阻塞)。Java 语言不允许将构造函数声明为 synchronized。2. 同步实例函数和同步静态函数争取的是不同的 locks。备注:两者均非多线程安全,可以使用实例变量进行同步控制,如(byte lock = new byte0),比其他任何对象都经济。3. 对于 synchronized 函数中可被修改的数据,应使之成为 private,并根据需要提供访问函数。如果访问函数返回的是可变对象,那么可以先克隆该对象。4. 避免无谓的同步控制备注:过度的同步控制可能导致代码死锁或执行缓慢。再次提醒,当一个函数声明为 synchronized,所获得的 lock 是隶属于调用此函数的那个对象。5. 访问共享变量时请使用 synchronized 或 volatile备注:如果并发性很重要,而且不需要更新很多变量,则可以考虑使用 volatile。一旦变量被声明为 volatile,在每次访问它们时,它们就与主内存进行一致化。如果使用
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号