Effective Java 笔记

创建和销毁对象

NO.1 考虑用静态工厂方法代替构造函数

静态工厂方法好处:

  • 1、构造函数有命名的限制,而静态方法有自己的名字,更加易于理解。
  • 2、静态工厂方法在每次调用的时候不要求创建一个新的对象。这种做法对于一个要频繁创建相同对象的程序来说,可以极大的提高性能。它使得一个类可以保证是一个singleton;他使非可变类可以保证“不会有两个相等的实例存在”。
  • 3、静态工厂方法在选择返回类型时有更大的灵活性。使用静态工厂方法,可以通过调用方法时使用不同的参数创建不同类的实例,还可以创建非公有类的对象,这就封装了类的实现细节。
  • 4、在创建参数化类型实例的时候,他们使代码变的更加简洁。

例如:

public static Boolean valueOf(boolean f){
	return b ? Boolean.TRUE : Booleab.FALSE;
}

Map<String,List<String>> m=HashMap.newInstance();

静态工厂方法坏处:

  • 1、如果一个类是通过静态工厂方法来取得实例的,并且该类的构造函数都不是公有的或者保护的,那该类就不可能有子类(被继承),子类的构造函数需要首先调用父类的构造函数,因为父类的构造函数是private的,所以即使我们假设继承成功的话,那么子类也根本没有权限去调用父类的私有构造函数,所以是无法被继承的。
  • 2、毕竟通过构造函数创建实例还是SUN公司所提倡的,静态工厂方法跟其他的静态方法区别不大,这样创建的实例谁又知道这个静态方法是创建实例呢?弥补的办法就是:静态工厂方法名字使用valueOf、of、getInstance、newInstance、getType、newType。

NO.2 遇到多个构造器参数时要考虑用构建器

当有多个构造方法,一般式参数大于4个的时候,建议使用Builder模式。

NO.3 用私有构造器或者枚举类型强化Singleton属性

用单元素的枚举来实现单例模式。

NO.4 通过私有的构造函数强化不可实例化的能力

在面向对象程序设计中,假如存在太多只有静态属性和静态方法的类;那么,面向对象的思想可能在这会损失殆尽。

但是,并不能说面向对象的程序中就不应该出现只有静态属性和静态方法的类,相反,有时候我们还必须写这样的类作为工具类。这样的类怎么实现呢?有人可能会把该类定义成抽象类(Abstract class),的确,抽象类是不可以实例化的,但是别忘了还有继承,继承了抽象类的子类在实例化时候,默认是会先调用父类无参数的构造函数的(super();),这时候,父类不是也被实例化了嘛?

其实我们可以这样做,把该类的构造函数定义为私有的(private),而类的内部又不调用该构造函数的话,就成功了。这样带来的后果就是该类成了 final的,不可能再被任何类继承了,要被继承,得提供一个公有(public)的或者保护(protect)的构造函数,这样才能被子类调用。

NO.5 避免创建重复的对象

如果一个对象是不可变的,那么他总是可以被重用的,如:

//不推荐,"test"本来就是一个String实例,如果此方法在一个循环中或者被频繁的调用,将会严重影响性能
String s = new String("test");
//推荐方式
String s = "test";

对于提供静态方法和构造函数的非可变类,推荐使用静态方法,这样可以避免重复创建对象,如:Boolean.vauleOf(String)方法优于构造函数Boolean(String)

类初始化的顺序:

先初始化父类的静态代码 —> 初始化子类的静态代码 —> 初始化父类的非静态代码 —> 初始化父类构造函数 —> 初始化子类非静态代码 —>初始化子类构造函数。

NO.6 消除过期的对象引用

内存泄漏问题:如果一个对象的引用被无意识的保留起来,那么垃圾回收机制是不会去处理这个对象,而且也不会去处理被这个对象引用的其它对象。 比如堆栈的弹出栈元素方法。

public Object pop(){

   if(size == 0){
       throw new EmptyStackException();
   }

	Object result = elements[--size];
	//自减后把原来的引用置为null
	elements[size] = null;
	return result;
}

内存泄露常出现在:

  • 过期对象
  • 缓存,由于缓存没有及时清除无用的条目而出现,可以使用weakHashMap来避免这种情况
  • 监听器和其他回调

清理过期对象引用的好处是:如果在以后又被使用到该引用,最会抛下NullPointException而不是让程序继续错误的运行下去,尽可能早的监测出程序中的错误总是有好处的。

方法:重新使用这个已经指向一个对象的引用,或结束其生命周期。

对所有对象都通用的方法

equals方法

(1) equals方法一般用于“值类”的情形,比如Integer,Date目的是为了比较两个指向值对象的引用的时候,希望 它们的逻辑是否相等而不是它们是否指向同一个对象。

约定:

  • a 自反性 对任意的对象必须和它自身相等。对值引用x x.equals(x) 一定返回true
  • b 对称性 对任意的值引用x,y,如果x.equals(y) 一定有y.equals(x)
  • c 传递性 对任意的值引用x,y,z,如果x.equals(y),y.equals(z) 一定有x.equals(z)
  • d 一致性 对于任何非null的引用x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true

结论:

要想在扩展一个可实例化的类的同时,即要保证增加新的特性,又要保证equals约定,建议复合优于继承原则。若类和类是 a kind of 关系则用继承,若类和类是 a part of 关系则用组合(复合)

hashCode

相等的对象必须要有相等的散列码,如果违反这个约定可能导致这个类无法与某些散列值得集合结合在一起使用,所以在改写了equals方法的同时一定要重写hashCode方法以保证一致性。

toString

toString返回值中包含所有信息

clone

Comparable

类和接口

  • 使类和成员的可访问能力尽量的小
  • 支持非可变性
  • 复合优于继承
  • 接口优于抽象
  • 优先考虑静态成员类

方法

  • (1) 检查参数的有效性
  • (2) 需要使用保护性拷贝
  • (3) 方法设计的一些原则 - a、避免长的参数列表,尤其是参数相同的参数列表。 - b、对参数类型使用接口,而不是接口的实现类。 - c、谨慎使用重载。 - d、返回0程度的数组而不是null。
  • (4) 为所有导出的api方法编写注释

重载(overloaded method) 选择的是静态的。选择的依据是参数类型

重写(oveeridden method) 选择的依据是被调用方法所在对象的运行时的类型。

通用设计方法

  • (1) 将局部变量的作用域最小化
  • (2) foreach优于传统的for循环。有三种情况无法使用foreach循环:过滤、转换、平行迭代
  • (3) 了解和使用类库
  • (4) 如果要得到精确结果,最好是用BigDecimal 而不使用fload或double
  • (5) 对数量大的字符串连接使用StringBuffer而不是String前者速度快。
  • (6) 基本类型优先于装箱类型
  • (7) 当心字符串连接性能
  • (8) 通过接口引用对象
  • (9) 接口优先于反射机制
  • (10) 谨慎使用本地方法
  • (11) 谨慎进行优化
时间: 2024-11-03 16:43:13

Effective Java 笔记的相关文章

Android应用开发提高系列(3)——《Effective Java 中文版》读书笔记

声明 欢迎转载,但请保留文章原始出处:)  博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com   书籍 <Effective Java 中文版> 03版 潘爱民译 本书介绍了57条极具实用价值的经验规则.这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案,通过对Java平台设计专家所使用的技术的全面描述,揭示了应坐什么和不应做什么,才能产生清晰.健壮和高效的代码.   正文  注意:条目和用语可能与书籍有所出入,但尽

effective java 学习笔记(一)

           最近在豆瓣上看到一些书评,很有感想,其中有一本叫 effective java据说很好,下载了看看,果然大作,很多东西都读不懂,功力尚浅,还得继续努力.读的时候感觉很爽,比讲语法的书好看多了. 第一部分 对象的创建和销毁. 讲了5条原则 1.用静态的工厂方法代替构造函数. 好处:避免创建重复的对象,因为静态的方法不许要创建对象就可以使用,造成不必要的浪费.重复返回同一个对象.保证单态. 工厂方法可以取更加容易记的名字,而构造函数则不行. 工厂方法可以返回一个原返回类型的子类

Effective Java --&amp;amp;gt;(一)创建和销毁对象

创建|对象 Effective Java学习笔记JAVA语言支持四种基本类型:接口(Interface).类(Class).数组(Array).和原语类型(Primitive).前三种类型通常被称为引用类型(reference type),类的实例和数组是对象(object),而原语类型的值不是对象.一个类的成员(member)包括它的域(field),方法(method),成员类(member class)和成员接口(member interface).一个方法的原型(signature)包括

Effective Java (1) 考虑用静态工厂方法代替构造器

一.前言 从今天开始计划用一个月的时间,通过写读书笔记的方式来记录阅读这本Java领域经典中的经典书籍 - Effective Java过程中自己所思所想,以备以后查阅,同时分享出去也希望可以帮助到其他人,废话不多说,现在开始第一篇:创建和销毁对象. 二.考虑用静态工厂方法代替构造器 ①. 一般我们有什么办法可以创建对象呢? 方法1: 使用类公有构造器. 方法2:使用类的静态方法返回一个实例. ②. 使用静态方法创建对象有什么优点? 优点1: 静态工厂方法的名字是由我们自己命名,而构造方法必须与

Effective Java (2) 遇到多个构造器参数时要考虑用构建器

一.背景 对于有多个可选参数的类,我们一般通过什么办法传递参数呢?这里提供了三种办法: ①. 重叠构造器模式 ②. JavaBeans模式 ③. Builder构建器模式 下面我们来分析一下以上三种方法的优势及弊端. 二.重叠构造器模式 重叠构造器模式中第一个构造器中只有必要参数,第二个构造器有一个可选参数,第三个构造器中有两个可选参数,依次类推,最后一个构造器中包含所有可选参数.这种方案可行,但是有较大缺陷. 缺点:当有很多可选参数的时候,客户端代码很难编写,并难以阅读,如果客户端不小心颠倒了

大话深入浅出Effective Java核心实战编程思想之猴王的把戏

不知道大家还记不记得在<西游记>里的莲花洞夺宝的故事,就是猴王巧夺宝物,收复金银角大王那 一章.到底这个故事给了我们什么启示呢?这故事又和Effective Java有什么联系?还是延续上篇文章的 风格吧,看代码,读故事. 1import static org.junit.Assert.*; 2import org.junit.Test; 3 4 5public class TestClone { 6 7 @Test 8 public void testClone(){ 9 // 西天取经的路

Android 中的 Effective Java(速查表)

本文讲的是Android 中的 Effective Java(速查表), Effective Java 是一本被广泛认可的著作,它指明了在写 Java 代码时兼顾可维护性与效率的方式.Android 也是使用 Java 来开发的,这意味着前书中的所有建议仍旧可用,真的是这样吗?并不尽然.某些同学 认为书中的"大部分"建议都不适用于 Android 开发,但我认为并不是这样.我承认书中的部分建议确实不适用,因为并非所有 Java 特性都有针对 Android 优化(比如说枚举,序列化等等

Java笔记:单例模式

什么是单例模式呢?就是在整个系统中,只有一个唯一存在的实例.使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收. 单例模式主要有3个特点: 1.单例类确保自己只有一个实例. 2.单例类必须自己创建自己的实例. 3.单例类必须为其他对象提供唯一的实例. 单例模式的实现方式有五种方法:懒汉,恶汉,双重校验锁,枚举和静态内部类. 懒汉模式: public class Singleton { private static Singleton instance;

Effective Java Second Edition中文版已出版

http://yulimin.javaeye.com/blog/340464 我自己今天才刚见到书:) 译者序 Java从诞生到日趋完善,经过了不断的发展壮大,目前全世界拥有了成千上万的Java开发人员.如何编写出更清晰.更正确.更健壮且更易于重用的代码,是大家所追求的目标之一.作为经典Jolt获奖作品的新版书,它已经进行了彻底的更新,涵盖了自第1版之后所引入的Java SE 5和Java SE 6的新特性.作者探索了新的设计模式和语言习惯用法,介绍了如何充分利用从泛型到枚举.从注解到自动装箱的