《Effective Java》学习总结
来源:互联网 发布:淘宝来图印花定制内裤 编辑:程序博客网 时间:2024/05/20 13:14
第一章:代码应该被重用,而不是被拷贝。模块之间的依赖性应该尽可能地降到最小。错误应该尽早被检测出来,最好是在编译时刻。
第2条:处理多参数构造器
public class NutritionFacts {private int servingSize;private int servings;private int calories;private int fat;public NutritionFacts(int servingSize, int servings) {this(servingSize, servingSize, 0); //调用了有三个参数的构造函数}public NutritionFacts(int servingSize, int servings, int calories) {this(servingSize, servings, calories, 0);}public NutritionFacts(int servingSize, int servings, int calories, int fat) {this.servingSize = servingSize;this.servings = servings;this.calories = calories;this.fat = fat;}}
第3条:实现Singleton的两种方式
①方式一
public class Elvis {public static final Elvis INSTANCE = new Elvis();//public域private Elvis(){//私有的构造函数}}
②方式二
public class Elvis {private static final Elvis INSTANCE = new Elvis(); //private的域private Elvis(){//私有的构造函数}public static Elvis getInstance(){return INSTANCE;}}
第5条:避免创建不必要的对象
String s = new String("stringette"); //Don't do this该语句每次被执行的时候都创建一个新的String实例,但是这些创建对象的动作全都是不必要的。传递给String构造器的参数"stringette"本身就是一个String实例,功能各方面等同于构造器创建的所有对象。
改进后的版本如下:
String s = "stringette";
基本类型和装箱基本类型:
public static void main(String[] args) {Long sum = 0L; //这意味着程序会构造大约2的31次方个多余的Long实例for (long i = 0; i < Integer.MAX_VALUE; i++) {sum += i;}System.out.println(sum);}将sum的声明从Long改为long,运行时间从43秒减少到了6.8秒。结论很明确,要优先使用基本类型而不是装箱基本类型。
第6条:一般而言,只要类是自己管理内存,程序员就应该警惕内存泄露问题。一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空。
public Object pop() {if (size == 0) {throw new EmptyStackException();Object result = elements[--size];elements[size] = null;// 清空对象引用return result;}}
第8条:
①使用instanceof操作符检查“参数是否为正确的类型”
②覆盖equals时总要覆盖hashCode
第13条:使类和成员的可访问性最小化
第19条:接口应该只被用来定义类型,它们不应该被用来导出变量
第24条:消除非受检警告
可以用@SuppressWarnings("unchecked")注解来禁止警告
第41条:慎用重载
“能够重载方法”并不意味着就“应该重载方法”。一般情况下,对于多个具有相同参数数目的方法来说,应该尽量避免重载方法。
第43条:返回零长度的数组或者集合,而不是null
对于一个返回null而不是零长度数组或者集合的方法,客户端每次都要判断方法返回的值是否为null这种曲折的处理方式。
第45条:将局部变量的作用域最小化
要使局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方声明。几乎每个局部变量的声明都应该包含一个初始化表达式。
第46条:for-each循环优先于传统的for循环
对集合和数组的遍历首选做法如下:
for(Element e : elements){ doSomething(e);}注意:这样做不会有性能上的损失,在某些情况下,比起普通的for循环,甚至还稍有性能优势。
第48条:如果需要精确的答案,请避免使用float和double
float和double类型尤其不适合用于货币计算。解决的办法是使用BigDecimal、int或者long进行货币计算。BigDecimal有两个缺点:与使用基本运算类型相比,这样做很不方便,而且很慢。在使用int和long时,需要自己处理十进制小数点。
另外,float和double都是线程不安全的。
第49条:基本类型优先于装箱基本类型
基本类型和装箱基本类型之间有三个主要区别:
①基本类型只有值,而装箱基本类型则具有与它们的值不同的同一性。
Comparator<Integer> naturalOrder = new Comparator<Integer>(){public int compare(Integer first,Integer second){return first < second ? -1 : (first == second);}};对于上面这段代码,如果比较Integer(42)和Integer(42),这两个Integer实例都表示相同的值42,因此这个比较器应该返回0,而事实上,它的输出却为1。这是因为还要对这两个对象引用进行同一性比较。当程序使用==操作符比较两个装箱基本类型时,它做了个同一性比较,这几乎肯定不是你所希望的;
②基本类型只有功能完备的值,而每个装箱基本类型除了它对应基本类型的所有功能之外,还有个非功能值:null;
③基本类型通常比装箱基本类型更节省时间和空间。
第51条:当心字符串连接的性能
为连接n个字符串而重复地使用字符串连接操作符(+, String concatenation operator),需要n的平方级的时间。如果数量巨大的字符串连接,为了获得可以接受的性能,请使用StringBuilder替代String。
第52条:通过接口引用对象
应该优先使用接口而不是类来引用对象,这样会使程序更加灵活。
第66条:同步访问共享的可变数据
Java语言规范保证读或者写一个变量是原子的(atomic),但是long和double类型除外,这两个类型变量不是线程安全的。
增量操作符(++)不是原子的。
当多个线程共享可变数据的时候,每个读或者写数据的线程,都必须执行同步。
第69条:并发工具优先于wait和notify
java.util.concurrent中更高级的工具分成三类:Executor Framework、并发集合(Concurrent Collection. 如ConcurrentMap)以及同步器(Synchronizer)
对于间歇式的定时,始终应该优先使用 System.nanoTime,而不是使用System.currentTimeMills。 System.nanoTime更加准确也更加精确,它不受系统的实时时钟的调整所影响。
第72条:不要依赖于线程调度器
线程优先级是Java平台上最不可移植的特征了。
- effective java 学习总结
- 《Effective Java》学习总结
- effective java 学习总结1
- 《Effective C++》学习总结
- Effective Java总结
- Effective JAVA 总结
- Effective Java 总结
- Java Effective 总结(0)
- effective java学习笔记
- Effective java学习笔记
- effective java学习笔记
- effective java 学习笔记
- Effective Java 学习笔记
- Effective Java 学习笔记
- Effective Java学习笔记
- Effective Java学习笔记
- Effective Java学习笔记
- Effective Java 学习笔记
- 华为:现有一串字符串,请找出其中的大写字母并顺序保存至output数组中
- Android 开发源码分享
- [IOS]消息提醒--TSMessages
- 第7周任务1:静态成员应用
- 贪心算法
- 《Effective Java》学习总结
- Oracle、Db2、SqlServer、MySQL 数据库插入当前系统时间
- POJ1006 Biorhythms
- Android Map 新用法:MapFragment
- [转]NodeJS初探
- 新一届ACM图灵奖得主以及其贡献
- Tiny 6410 K9GAG08U0E nand flash移植uboot
- 错误集锦
- Hive调优实战