创建和销毁bean
笔记:
create and destory bean:
1、考虑用静态工厂方法代替构造器
优势:有名称
不必在每次调用它们时候都创建一个新对象
可以返回原返回类型的任意子类型对象
在创建参数化类型实例的时候,它们使代码变得更加简洁
缺点:
类如果不含有公有的或者被保护的构造器,就不能被子类化
与其他的静态方法实际上没有任何区别
2、遇到多个构造器参数时要考虑用构建器
重叠构造器
javaBean模式。因为构造过程被分到了几个调用中,在构造过程中javaBean可能处于不一致的状态;javaBeans阻止了把类做成不可变的可能,这就需要程序员付出额外努力保证它的线程安全。
Builder模式:劣势:开销额外,冗长
3、用私有构造器或者枚举类型强化Singleton属性
生成单例:
1、公有静态成员是final
2、公有的成员是个静态工厂方法
3、枚举
4、通过私有构造器强化不可实例化的能力
私有构造抛异常,导致子类不能实例化
5、避免创建不必要的对象
同时提供了静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器
作用域提升
自动装箱:优先使用基本数据类型而不是包装类型,当心无意识的自动装箱
6、消除过期的对象引用
清空对象引用应该是一种例外而不是一种规范行为。最好的方法是让包含该引用的变量结束其生命周期
一般而言,只要是类自己管理内存,程序员就应该警惕内存泄露问题
内存泄露的另一个常见来源是缓存,如果key依赖引用的话可以考虑使用weakHashMap替代缓存,缓存除了自动清除也可以由后台线程完成或者新增时候触发清理
内存泄露的第三个常见来源是监听器和其他回调
7、避免使用终结方法
终结方法finalizer通常是不可预测的,也是很危险的,一般情况下是不必要的。使用终结方法会导致行为不稳定、降低性能,以及可移植性问题。c++中说:“不要把终结方法当做是C++中析构器的对应物”,在c++中,析构器是回收一个对象所占用资源的常规方法,是构造器所必须的对应物。在java中,当一个对象变得不可到达的时候,垃圾回收器会回收与该对象相关联的存储空间。c++的析构器也可以被用来回收其他的内存资源。而在java中,一般用try-finally块完成类似操作。
终结方法的缺点在于不能保证会被及时执行
java语言规范不保证终结方法会被及时执行,而且根本就不保证它们会被执行,结论是不应该依赖终结方法来更新重要的持久状态
未捕获的异常在终结过程中被跑出来会终止掉该对象的终结过程
使用终结方法有一个很严重的性能损失
如果类的对象中封装的资源确实需要终止,可以提供一个显式的终止方法,并要求该类的客户端在每个实例不再有用的时候调用这个方法。值得一提的细节是,该实例必须记录下自己是否已经被终止了。显示终止方法的经典例子是InputStream、OutputStream和Connection的close方法。显式的终止方法通常与try-finally结构结合使用,以确保及时终止。
有关代码:
package chapter1; /** * @author zhen * @Date 2018/9/27 11:09 */ public class CaculateInteger { public static void main(String[] args) { long begin = System.currentTimeMillis(); Long sum = 0L;//这里声明为Long就意味着程序多构造了2^31多余的Long实例 for (long i = 0; i < Integer.MAX_VALUE; i++) { sum += i; } long end = System.currentTimeMillis(); System.out.println(end-begin); } }
Elvis
package chapter1; import java.io.Serializable; /** * @author zhen * @Date 2018/9/27 10:19 */ public class Elvis2 implements Serializable { private static final Elvis2 INSTANCE = new Elvis2(); private Elvis2() {} public static Elvis2 getInstance () { return INSTANCE; } /** 这个方法是防止反序列化的时候创建新的实例 */ private Object readResource() { return INSTANCE; } public void leaveTheBuilding() {} }
package chapter1; /** * @author zhen * @Date 2018/9/27 10:23 */ public enum Elvis3 { INSTANCE; public void leaveTheBuilding() { } }
package chapter1; /** * @author zhen * @Date 2018/9/27 10:04 */ public class NuritionFacts2 { private int servingSize; private int servings; private int calories; private int fat; private int sodium; private int carbohydrate; public static class Builder { private final int servingSize; private final int servings; private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat (int val) { fat = val; return this; } public Builder sodium(int val) { sodium = val; return this; } public Builder carbohydrate(int val) { this.carbohydrate = val; return this; } public NuritionFacts2 build() { return new NuritionFacts2(this); } } private NuritionFacts2 (Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } }
package chapter1; /** * @author zhen * @Date 2018/9/27 9:46 */ public class NutritionFacts { private int servingSize; private int servings; private int calories; private int fat; private int sodium; private int carbohydrate; public NutritionFacts(int servingSize, int servings) { this(servingSize, servings, 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, servings, calories, fat, 0); } public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) { this(servingSize, servings, calories, fat, sodium, 0); } public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) { this.servingSize = servingSize; this.servings = servings; this.calories = calories; this.fat = fat; this.sodium = sodium; this.carbohydrate = carbohydrate; } }
package chapter1; /** * @author zhen * @Date 2018/9/27 9:54 */ public class NutritionFacts1 { private int servingSize = -1; private int servings = -1; private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public NutritionFacts1() {} public void setServingSize(int servingSize) { this.servingSize = servingSize; } public void setServings(int servings) { this.servings = servings; } public void setCalories(int calories) { this.calories = calories; } public void setFat(int fat) { this.fat = fat; } public void setSodium(int sodium) { this.sodium = sodium; } public void setCarbohydrate(int carbohydrate) { this.carbohydrate = carbohydrate; } }
package chapter1; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; /** * @author zhen * @Date 2018/9/27 10:44 */ public class Person { private final Date birthDate; public Person(Date birthDate) { this.birthDate = birthDate; } public boolean isBabyBommer() { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); Date boomStart = gmtCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); Date boomEnd = gmtCal.getTime(); return birthDate.compareTo(boomStart) >= 0 && birthDate.compareTo(boomEnd) < 0; } }
package chapter1; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; /** * @author zhen * @Date 2018/9/27 10:48 */ public class Person1 { private final Date birthDate; private static final Date BOOM_START; private static final Date BOOM_END; static { Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0); BOOM_START = gmtCal.getTime(); gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0); BOOM_END = gmtCal.getTime(); } public Person1(Date birthDate) { this.birthDate = birthDate; } public boolean isBabyBommer() { return birthDate.compareTo(BOOM_START) >= 0 && birthDate.compareTo(BOOM_END) < 0; } }
package chapter1; /** * @author zhen * @Date 2018/9/27 9:23 */ //Service provider interface public interface Provider { Service newService(); }
package chapter1; /** * @author zhen * @Date 2018/9/27 9:23 */ public interface Service { //Service-specific methods go here }
package chapter1; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author zhen * @Date 2018/9/27 9:35 */ public class Services { private Services() {} private static final Map<String, Provider> providers = new ConcurrentHashMap<>(); private static final String DEFAULT_PROVIDER_NAME="<def>"; public static void registerDefaultProvider(Provider p) { registerProvider(DEFAULT_PROVIDER_NAME, p); } public static void registerProvider(String name, Provider p) { providers.put(name, p); } public static Service newInstance() { return newInstance(DEFAULT_PROVIDER_NAME); } public static Service newInstance(String name) { Provider p = providers.get(name); if (p == null) { throw new IllegalArgumentException("No provider registered with name:" + name); } return p.newService(); } }
package chapter1; import java.util.Arrays; import java.util.EmptyStackException; /** * @author zhen * @Date 2018/9/27 11:38 */ public class Stack implements Cloneable{ private Object[] elements; private int size = 0; private static final int DEFAULT_INITIAL_CAPACITY = 16; public Stack() { elements = new Object[DEFAULT_INITIAL_CAPACITY]; } public void push(Object e) { ensureCapacity(); elements[size++] = e; } public Object pop(){ if (size == 0) { throw new EmptyStackException(); } Object result = elements[--size]; elements[size] = null; return result; //这里可能会出现内存泄露,因为栈内部维护过期引用 return elements[--size]; } private void ensureCapacity() { if (size == elements.length) { elements = Arrays.copyOf(elements, 2 * size + 1); } } //简单使用super.clone会导致elements域将返回与原Stack实例相同的数组。修改原始的实例会破坏克隆对象中的约束条件,反之亦然 @Override public Stack clone () { try{ Stack result = (Stack) super.clone(); result.elements = elements.clone(); return result; } catch (CloneNotSupportedException e){ throw new AssertionError(); } } }
package chapter1; /** * @author zhen * @Date 2018/9/27 10:31 */ public class UtilityClass { //Suppress default constructor for noninstantiability private UtilityClass() { throw new AssertionError(); } }

浙公网安备 33010602011771号