《spring 3.X企业应用开发实战》
1.资源范围利器:P53 ?:匹配文件中的一个字符 *:匹配文件中任意字符 **:匹配多层路径 eg:classpath*:org/**/s*.xml
2.介绍beanFactory和ApplicationContext的关系 P58
3.介绍依赖注入的三种形式 P86
<<effective java>>
1.静态工厂方法代替构造器的优劣:P4
优势:
①静态工厂方法有名称
②不必每次调用的时候都创建一个新的对象
③可以根据参数的不同返回任意子类型的对象
基于接口的框架,对于客户端是不可见的,未来修改返回的对象,对客户端没有影响
④创建参数化类型实例的时候,使代码变的简洁
eg:
Map<String, List<String>> m = new HashMap<String, List<Sring>>(); 修改为Map<String, List<String>> m = HashMap.newInstance(); public static <K, V> HashMap<K, V> newInstance(){ return new HashMap<K, V>(); }劣势:
public class T1 { private T1(){ } public T1(String a){ } }
2.遇到多个构造器参数时,考虑使用构建器(build) P9
重叠构造器、静态工厂方法当遇到多个参数时,会变的比较难阅读,如果没有详细的文档,容易出错,出了错,还比较难排查
javaBean的方式弥补了重叠构造器的缺点,但是它不安全
build即可以像构造器那样安全,也能像JavaBean有那么好的可读性,但是会花费一定的开销,代码比重叠构造器要冗长。因此只有在参数的多的情况,才考虑使用
public class TestBuild { private final int a; private final int b; private final int c; private final int d; private final int e; private final int f; public static class Builder{ // 必须的参数 private final int a; private final int b; // 可选的 private int c = 0; private int d = 0; private int e = 0; private int f = 0; public Builder(int a, int b){ this.a = a; this.b = b; } public Builder c(int val){ this.c = val; return this; } public Builder d(int val){ this.c = val; return this; } public Builder e(int val){ this.c = val; return this; } public Builder f(int val){ this.c = val; return this; } public TestBuild build(){ return new TestBuild(this); } } private TestBuild(Builder builder){ a = builder.a; b = builder.b; c = builder.c; d = builder.d; e = builder.e; f = builder.f; } }
TestBuild test = new TestBuild.Builder(100, 10).c(300).e(200).build();
3.创建singleton实例 P14
有三种方法
①公有域方法(类成员的声明很清楚的表明了这个类是个singleton)
public class TestSingleton{ public static final TestSingleton instance = new TestSingleton(); private TestSingleton(){} }②静态工厂方法(可以在不改变API的前提下,可以改变该类是否应该为singleton的想法)
public class TestSingleton implements Serializable{ private static final TestSingleton instance = new TestSingleton(); private TestSingleton(){} public static TestSingleton getInstance(){return instance;}; // 序列化遇到单例时,从内存中读出组装的对象破坏了单例的规则,因为反序列化时,克隆出了一个新的对象 // 当jvm从内存反序列化时,就会自动调用这个 readResolve方法来返回我们指定好的对象了, 单例规则也就得到了保证. private Object readResolve() throws ObjectStreamException { return instance; } }
public enum TestEnum { INSTANCE; public void test(){ } }与公有域方法相近,更简洁,无常的提供序列号机制,绝对防止多次实例化
4.通过私有构造器强化不可实例化的功能 P16
这种类一般指的工具类
5.避免创建不必要的对象 P17
①
String aa = new String("123456"); // 每次调用都产生新的对象
String aa = "123456"; // 只有一个实例,可以保证,在同一台虚拟机中运行的代码,只要包含相同的字符串字面变量,该对象就会被重用
③重用那些已知不会被修改的可变对象,即对象修改为final静态域,也可以进行延迟初始化(不建议这么做,会使方法变的复杂,而且无法显著的提高性能)
④Map的keyset返回Map对象的Set视图,看起来好像每次调用keyset都会创建新的Set实例,实际上对于一个给定的Map对象,每次调用keyset都返回同样的Set实例
⑤自动装箱和拆箱(要优先使用基本数据类型,而不是装箱基本类型)
Long sum = 0L; for(long i = 0; i < Integer.MAX_VALUE; i++){ sum += i; }上面这段程序就构造了2的31次方个多余的Long实例,性能大大折扣
⑥对象池不要乱用,除非池中的的对象是非常重量级的,如数据库连接池。对象池会使你的代码很乱,同时增加内存占用。
⑦保护性拷贝指的是“当你应该创建新对象的时候,请不要重用现有的对象”,是与本条想对应的。不重用对象只会影响程序的风格和性能;但是没有实施必要的保护性拷贝,将会导致潜在的错误和安全漏洞