第一章-创建和销毁对象 的一些 小tips
不希望被实例化 又不想抽象化
某些类不希望被实例化出毫无意义的对象 但不编写显示构造器类会自定义一个隐式无参的构造器 因此可以用一下方式,编写不能实例化的类:
public class UtilityClass{
private UtilityClass(){
throw new AssertionError();//直接抛出assert验证异常 好坏
}
}
该构造器是私有的。其他类不能过访问(即使同包)。
不要创建没必要的对象
不可变的对象一定要重用(singleton);重用绝逼不会变的对象(例如计时初始时间、例如物种的属性)。例如,实例化Person对象的时候判断是不是计划生育年代出生的,即判断出生年份是否在1983-2015年。
class Person{
private final Date birthDate;
private static final Date BIRTH_START;
//这俩参数都是不变的 为了对比出生时间
//没必要每次都创建一个日期对象,只在初始化时调用。
private static final Date BIRTH_END;
//静态块的方法 第一次声明Person对象时构建(不用实例化)
// 后面占用一块内存 不用再次创建
static{
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1983,Calendar.JANUARY,1,0,0,0);
//这里对日期做了时区判断
//保证都是从某一客观时间点出生的
BIRTH_START = gmtCal.getTime();
gmtCal.set(2016,Calendar.JANUARY,1,0,0,0);
//截止2015年年底 所以取2016年年初
BIRTH_END = gmtCal.getTime();
}
public boolean isJiHuaShengYu(){
return birthDate.compareTo(BIRTH_START) >=0 &&
birthDate.compareTo(BIRTH_END) <=0;
}
}
如果isJiHuaShengYu方法从未调用,这个方法就显得不合时宜了,这块静态块的内存就一直占着,因此,可以采用延时初始化的方式,在第一次调用该方法时调用。
adapter适配器模式可以提供一个后备对象,使实例化次数减少(包括类适配器和对象适配器);autoboxing自动装箱模式能够自动创建多余对象,所以尽量少用,而使用基本数据类型。
适配器Adapter
adapter工作场景
适配器模式工作场景是:给定的一个接口不满足需求,需要其一些功能与其他的接口或类配合使用.正如已经给了电压和充电插座,但是插座电压与设备工作电压,这是时候就需要一个转换接头。
adapter分类
一般分为类适配器和对象适配器。类适配器一般继承了给定接口的被适配类,同时拓展实现了标准的接口;而对象适配器则直接关联,以委托的方式完成已知接口的特殊功能。
类适配器实例:Adaptee(已知的待适配的类) Target(目标类) Adapter(适配器类)
可以看到,类适配器的方式通过继承或实现接口的方式,来传递某些功能或方法,以达到利用已知功能的目的。
// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Adaptee {
public void specificRequest() {
System.out.println("被适配类具有 特殊功能...");
}
}
// 目标接口,或称为标准接口
interface Target {
public void request();
}
// 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
public void request() {
System.out.println("普通类 具有 普通功能...");
}
}
// 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target{
public void request() {
super.specificRequest();
}
}
// 测试类
public class Client {
public static void main(String[] args) {
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();
// 使用特殊功能类,即适配类
Target adapter = new Adapter();
adapter.request();
}
}
对象适配器实例 Adapter适配器类 被适配器同上
对象适配器则通过对被适配类实例化,通过其对象获取其中部分功能,委托这一实例来完成想要传递的方法。
// 适配器类,直接关联被适配类,同时实现标准接口
class Adapter implements Target{
// 直接关联被适配类
private Adaptee adaptee;
// 可以通过构造函数传入具体需要适配的被适配类对象
public Adapter (Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
// 这里是使用委托的方式完成特殊功能
this.adaptee.specificRequest();
}
}
public class Client {
public static void main(String[] args) {
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();
// 使用特殊功能类,即适配类,
// 需要先创建一个被适配类的对象作为参数
Target adapter = new Adapter(new Adaptee());
adapter.request();
}
}
参考这里
##
autoboxing方式