//静态工厂方法代替构造器
//优势: 1.有名称 2.不用每次调用都创建新的对象 3.可以返回原返回类型的任何子类型对象
//4. 返回的对象可以随着每次调用而发生变化 取决于静态方法的参数值
//5. 方法返回的对象所属的类 在编写该静态工厂方法的类时可以不存在
//缺点: 1.类不含公有或受保护的构造器 就不能被子类化 鼓励使用复合而不是继承(不可变类) 2.很难被程序员发现
public static Boolean valueOf(boolean b){
return b?Boolean.TRUE:Boolean.FALSE;
}
//惯用名称
public void test(){
Instant instant = null;
Date d=Date.from(instant);
}
//遇到多个构造器参数时要考虑使用构造器
//参数较多时 重叠构造器可行 但是难编写难阅读
// 替代方案: 调用无参构造函数创建对象 再使用setter方法 JavaBeans模式 缺点:构造过程中JavaBean可能状态不一致 把类做成不可变的可能性不复存在
//第三种方式: 建造者模式---不直接生成想要的对象,让客户端利用所有必要的参数调用构造器(或静态工厂)得到一个builder对象 在builder对象上调用类似setter对象的方法
// 设置每个相关的可选参数 最后调用无参的build方法生成不可变的对象模拟了具名的可选参数
//建造者模式也适用于类层次结构
public class NutritionFacts{
private final int servingSize;
private final int servings;
private final int fat;
private final int sodium;
public static class Builder{
private final int servingSize;
private final int servings;
private int fat=0;
private int sodium=0;
public Builder(int servingSize,int servings){
this.servings=servings;
this.servingSize=servingSize;
}
public Builder fat(int val){
this.fat=val;
return this;
}
public Builder sodium(int val){
this.sodium=val;
return this;
}
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder){
servingSize=builder.servingSize;
servings=builder.servings;
fat=builder.fat;
sodium=builder.sodium;
}
}
public static void main(String[] args) {
NutritionFacts cocaCola=new NutritionFacts.Builder(240,8).sodium(10).fat(1).build();
}
//用私有构造器或枚举 强化Singleton属性 (仅被实例化一次的类)
public class Elvis{
private static final Elvis INSTANCE=new Elvis();
private Elvis(){}
public static Elvis getInstance(return INSTANCE;);
//可序列化 防止序列化创创建新的对象
private java.lang.Object readResolve(){
return INSTANCE;
}
}
//氮元素的枚举类型 实现单例化的最佳方法
public enum Elvis{
INSTANCE;
}
//通过私有构造器强化不可实例的能力 减少没意义的实例化的损耗
//做成抽象类是不可以的 可以被子类化然后子类可以被实例化
//让类包含一个私有构造器 它就不能被实例化了
public class UtilityClass{
private UtilityClass(){
throw new AssertionError();
}
}
//优先考虑依赖注入来引用资源 静态工具类和Singleton 不适合需要引用底层资源的类
//使用依赖注入: 当创建一个新的实例时,就将该资源传到构造器中
public class SpellChecker{
private final Lexicon dictionary;
private SpellChecker(Lexicon dictionary){
this.dictionary= Objects.requireNonNull(dictionary);
}
}
//避免创建不必要的对象
//反面例子
String s=new String("aaa");
//优先使用静态工厂而不是构造器 避免创建不必要的对象
//对于复杂重复使用的对象 将其进行缓存
public class RomanNumerals{
private static final Pattern ROMAN=Pattern.compile("...");
static boolean isRomanNumeral(String s){
return ROMAN.matcher(s).matches();
}
}
//优先使用基本类型而不是装箱基本类型 当心无意义的自动装箱
//消除过期的对象引用
//举例 一个栈对象 设置 当满了就把容量 *2 ,但是一个栈先增长再收缩 从栈中弹出来的对象就不会被回收 栈内部维护了其过期引用 导致内存泄露
//解决方法:一旦引用对象过期,就立即清空这些引用
public Objects pop(){
Objects result=elements[--size];
elements[size]=null;
return result;
}
//避免使用终结方法和清除方法
//注重时间的任务不应该由终结方法或者清除方法来实现 例如 关闭一个打开的文件
//终结方法和清除方法的合法途径: 1.当资源所有者忘记close时,终结或者清除方法可以充当 安全网
//2.处理本地对等体 (非Java对象)
//try-with-resource 优先于 try-finally
static String firstLineOfFile(String path) throws FileNotFoundException {
try(BufferedReader br=new BufferedReader(
new FileReader(path);
))
}