![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Effective java
灬叛逆丿文
这个作者很懒,什么都没留下…
展开
-
如何优雅的创建对象(一)
第一条:静态工厂方法代替构造器在创建对象的时候大部分程序员都是直接用new的形式。下面来讲解另一个创建对象的方式,用静态工厂方法代替构造器。比如我们想得到一个Integer对象,可以直接new得到,也可以用Integer.valueOf()这个静态方法直接得到。 int a = 5; Integer b = new Integer(a); In...原创 2019-05-14 13:23:40 · 664 阅读 · 0 评论 -
第19 条:要么设计继承并提供文档说明,要么禁止继承
要么设计继承并提供文档说明,要么禁止继承该类的文档必须精确地描述覆盖每个方法所带来的影响对于非私有方法包括构造器的文档说明上必须标注这个方法调用了哪些可以被覆盖的类,是什么顺序调用的,调用结果是怎么影响后续方法处理的。可以被覆盖的类是指非final的、公有的、受保护的方法,后台线程或者静态初始化器可能会调用可被覆盖的方法。调用的方法的文档末尾会有调用描述信息,写着: “ Implementa...原创 2019-05-22 10:25:07 · 200 阅读 · 0 评论 -
第20 条:接口优于抽象类
接口优于抽象类定义:接口:没有方法实现(当然jdk1.8新加的default不算)抽象类:可以有方法实现区别:接口:允许多实现抽象类:只能单根继承优缺点接口不会改变类的层级,抽象类会改变类的层级。如何理解,比如抽象类People有三个子类,学生,老师和父亲,他们是一个层级的,都是people的子类。、现在我们又有个抽象类audit只需要teacher和father类来继承,而...原创 2019-05-22 13:25:52 · 183 阅读 · 0 评论 -
第21 条: 为后代设计接口
为后代设计接口java8之前,为接口添加一个方法,还得去破坏所有的子类代码才可以,因为你接口添加了方法,子类得去实现这个方法,不实现就会编译不通过,但是在java8之后增加了缺省方法,可以在接口中添加方法了。比如有接口B,有a,b两个方法public interface B { public abstract void a(); public void b();}类C实...原创 2019-05-22 13:39:48 · 330 阅读 · 0 评论 -
第13 条: 谨慎地覆盖clone
第13 条: 谨慎地覆盖clone1.一个类要想实现clone,就要实现Cloneable接口,否则抛出异常2.Cloneable接口的功能就是为了改变Object类中clone方法以返回对象的clone值,这种接口用法不推荐。3.不可变类不能提供clone方法。4.clone是浅拷贝,概念参考我的另一篇文章clone深浅拷贝,往往clone出来的对象里面的成员变量和原始的是一个引用,原始...原创 2019-05-17 10:20:02 · 163 阅读 · 0 评论 -
第14 条:考虑实现Comparable 接口
考虑实现Comparable接口实现这个接口的类就可以比较大小,比如你想对集合中的对象进行排序,那总得知道排序规则吧,这个接口就是定义排序规则的。下面是Comparable接口,里面只有一个compareTo方法package java.lang;import java.util.*;public interface Comparable<T> { public ...原创 2019-05-17 10:47:24 · 213 阅读 · 0 评论 -
第15 条:使类和成员的可访问性最小化
第15 条:使类和成员的可访问性最小化核心思想就是封装,对外只暴漏接口,隐藏具体实现。尽可能使每个类或者成员不被外界访问到。对类而言:访问修饰符只有两种 //没有访问修饰符,默认就是包级私有类,只有同包类可以调用 class User { } //pulic修饰,类在哪儿都可以调用 public class User { }如果一个类只是在同包的其他类...原创 2019-05-17 11:24:15 · 246 阅读 · 0 评论 -
第22 条:接口只用于定义类型
接口只用于定义类型喂,说的就是你,在接口里面定义常量的行为,常量是类的实现细节,这样不仅把实现细节泄露出去,哪天不用这些常量了为了二进制兼容性还不得不维护这个接口,大大的污染了类的命名空间简而言之,接口应该只被用来定义类型, 它们不应该被用来导出常量。...原创 2019-05-22 14:50:30 · 238 阅读 · 0 评论 -
第26 条: 请不要使用原生态类型
泛型请不要使用原生态类型泛型是java1.5引进来的,什么是泛型我就不多说了。什么是原生态类型:这是原生态的,没有<>List list = new ArrayList<>();这是非原生态的,即有<>List<String> list = new ArrayList<>();泛型的作用有两点1.编译时检查我们所放入的...原创 2019-05-22 16:43:16 · 307 阅读 · 0 评论 -
第16 条:要在公有类而非公有域中使用访问方法
要在公有类而非公有域中使用访问方法核心意思就是:访问成员变量要用setter和getter方法。为啥子咧?下面是在User类中要对属性age进行赋值,一顿赋值我想让你的年龄是多少岁都行,这有点儿不科学啊。 class User { public int age; public static void main(String[] args) { new...原创 2019-05-17 16:06:22 · 259 阅读 · 0 评论 -
第17 条:使可变性最小化
使可变性最小化核心思想能把类做成不可变的就做成不可变的,比如String,Integer,Long等即使不能做成不可变的,也要尽可能的使类的成员变量变成private final的。优点1.不可变对象比较简单。不可变对象可以只有一种状态,即被创建时的状态。2.不可变对象本质上是线程安全的,并发状态下不用额外考虑他们。当多个线程并发访问这样的对象时,它们不会遭到破坏。3.不可变对象可以...原创 2019-05-17 17:40:12 · 190 阅读 · 0 评论 -
第12 条:始终要覆盖toString
始终要覆盖toString这个这是建议,覆盖不覆盖对程序本身的运行是不产生影响的,它只是由于在调试的时候更想看到的是覆盖后输出的对象有用的信息。public class User { private String name; private int age; private String address; public User(String name, in...原创 2019-05-16 16:58:18 · 151 阅读 · 0 评论 -
覆盖equals时总要覆盖hashCode
覆盖equals时总要覆盖hashCode基于散列的集合例如HashSet,HashMap在判断是否是同一个对象的时候是先判断他们的hashCode是否相等,如果相等再判断equals是否相等,都相等两个对象才相等,而如果hashCode不相等就说明两个对象不相等,没有必要比较equals了。下面是来自Object的规范:1.在应用程序的执行期间,只要对象的equals 方法的比较操作所用到...原创 2019-05-16 16:43:54 · 280 阅读 · 0 评论 -
遇到多个构造器参数时要考虑使用构建器
遇到多个构造器参数时要考虑使用构建器当程序员需要写一个类里面包含大量的必选参数和可选参数的时候,大部分是采用重叠构造器的模式,第一个构造器里面包含的是必选参数,第二个构造器里面多加了一个可选参数,第三个构造器里面又多加了一个,一次类推。例如下面就是重叠构造器,name属性是必须的,然后其他的参数都有默认值。package com.tk.portal.bean;public class ...原创 2019-05-15 14:50:04 · 246 阅读 · 0 评论 -
第18 条:复合优先于继承
复合优先于继承核心:对于专门为了继承而设计并且具有很好的文档说明的类来说,使用继承是非常安全的。然而,对普通的具体类进行跨越包边界的继承,则是非常危险的。论证与方法不同的是,继承打破了封装性咋的理解了?看如下的例子public class A { //方法功能是说话 public void say() { //一堆说话的实现细节 } //...原创 2019-05-20 15:27:49 · 255 阅读 · 0 评论 -
用私有构造器或者枚举类型强化Singleton 属性
用私有构造器或者枚举类型强化Singleton 属性实现Singleton有两种常用方法第一种public class User { //定义为final的,保证只有一份实例化 public static final User INSTANCE = new User(); //将构造器私有,防止通过构造器创建对象 private User(){ ...原创 2019-05-15 15:59:43 · 117 阅读 · 0 评论 -
通过私有构造器强化不可实例化的能力
通过私有构造器强化不可实例化的能力比如下面的Math类,它只包含静态域和静态方法,这个类的用法就是直接就是用类名点调用方法。这种类大部分是作为工具类来使用,所以实例化这种类是没有任何意义的,为了防止这种类被实例化,通过设置它们的构造器为私有来阻住他们实例化。并且这种类是不能有子类的。因为所有的子类都显式或者隐式的调用了超类的构造器。package java.lang;import ja...原创 2019-05-15 16:12:48 · 199 阅读 · 0 评论 -
优先考虑依赖注人来引用资源
优先考虑依赖注人来引用资源有许多类需要依赖底层资源,比如我们有个类需要依赖底层的字典资源,像下面这样做成静态域的,或者把类做成Singleton的都是很常见的。public class Word { private static final Dictionary DICTIONARY = new Dictionary();}但是这只是作为有一本字典的情况下,当我们在不同的情况下需...原创 2019-05-15 16:45:12 · 421 阅读 · 0 评论 -
避免创建不必要的对象
避免创建不必要的对象核心思想就是,能用一个实例就不要创建两个实例。这种情况一般是用在重量级的对象上面,比如JDBC连接池,创建一个数据库连接对象是非常损耗性能的一个操作,而且有的数据库对于连接上限也是有限制的,所以为了避免每次连接数据库的时候都要重新创建一个对象,就要维护一个数据库连接池,每次进行连接的时候不是创建新对象,而是重用连接池里面的对象。又比如String类型的,当我们用new S...原创 2019-05-15 17:01:33 · 98 阅读 · 0 评论 -
第七条:消除过期的对象引用
消除过期的对象引用java虽然有垃圾回收器,但是不是说在任何情况下都不用考虑内存泄露的问题了。下面例子是一个简单的栈,包括入栈出栈。public class Stack { private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY...原创 2019-05-16 14:07:25 · 141 阅读 · 0 评论 -
第八条:避免使用终结方法和清除方法
避免使用终结方法和清除方法finalizer清除方法我想大家在java面试的时候早就是司空见惯了,在java9中用cleaner代替了finalizer,虽然标题是禁止使用这个方法,但是我认为即使推荐你用,也没有几个人会用的,我只是面试的时候看看这个东西是啥就行了,想让我用,那不可能。使用这个方法也就是标记让清除对象而已,但是这个方法的运行往往是不可预测,效率低下的,有可能会发生奇怪的现象,所...原创 2019-05-16 14:25:31 · 314 阅读 · 0 评论 -
第9 条: try-with-resources 优先于try-finally
try-with-resources 优先于try-finally我们一般在关闭资源的时候都会选用try-finally,比如关闭各种读写流,数据库连接对象等,都会在finally中调用对象的close方法,即使发生异常也会确保资源被释放,这看上去没有什么问题。但是再添加另一个资源,就会显的乱七八糟的感觉,如下是文件拷贝代码示例。 public static void copy(Str...原创 2019-05-16 15:21:20 · 423 阅读 · 0 评论 -
第十条:覆盖equals时请遵守通用约定
覆盖equals时请遵守通用约定我们应该知道,equals方法是Object的方法,是用的==比较,即比较是否是同一个对象 public boolean equals(Object obj) { return (this == obj); }但是大多数情况下我们要的不是对象相等即为相等,而是逻辑上的相等,常见的比如String类型的,只要字符相等我们就认为他们...原创 2019-05-16 16:08:05 · 149 阅读 · 0 评论 -
第50 条:必要时进行保护性拷贝
必要时进行保护性拷贝核心思想不可变类可以轻易的被外部对象改变,所以在必要时要进行保护性拷贝。比如下面的类,可以生成一个不可变类,因为他的域都是final的,但是外部可以通过将传递进来的引用进行改变,实则就会改变这个不可变类,可能导致错误的发生。public class C { private final Date start; private final Date end...原创 2019-05-24 10:43:10 · 153 阅读 · 0 评论