Effective Java笔记(一)

第1条:考虑用静态工厂方法代替构造器

优势:
1. 静态工厂方法有名称。构造器只能与类名相同,而静态工厂方法名能取得更有意义。
2. 不必多次构建对象。
3. 可以返回原返回类型的任何子类型的对象。
4. 使代码更简洁。
构造器:Map<String, List<String>> m = new HashMap<String, List<String>>();
静态工厂:Map<Stirng, List<String>> m = HashMap.newInstance();

缺点:
1. 类如果不含 public 或 protect 的构造器,就不能被子类化。
2. 与其他静态方法实际上没有任何区别。

第2条:构造器有多个参数时要考虑用构建器

当遇到构造器有多个可选参数时,不使用重载构造器,而使用构建器:

public class User{
    private final String account;
    private final String password;
    private final String name;
    private final int age;

    public static class Bulider{
        //必要参数
        private final String account;
        private final String password;

        //选填缺省参数值
        private final String name = null;
        private final int age = 0;

        public Builder(String account, String password){
            this.account = account;
            this.password = password;
        }

        public Builder name(String val){
            this.name = val;
            return this;
        }

        public Builder age(int val){
            this.age = val;
            return this;
        }

        public User bulid(){
            return new User(this);
        }
    }

    private User(Builder builder){
        account = builder.account;
        password = builder.password;
        name = builder.name;
        age = builder.age;
    }
}

使用时只要:

User user = new User.Builder("admin","123456")
                    .name("userName")
                    .age(20)
                    .build();

第3条:用私有构造器或者枚举类型强化Singleton属性

方法一:

public class Elvis{
    //公有
    public static final Elvis INSTANCE = new Elvis();
    private Elvis(){...}
    ...
}

//调用
Elvis.INSTANCE; 

方法二:

public class Elvis{
    //私有
    private static final Elvis INSTANCE = new Elvis();
    private Elvis(){...}
    public static Elvis getInstance(){
        return INSTANCE;
    }
    ...
}

//调用
Elvis.getInstance();    

为防止客户端通过反射机制调用私用构造器,可以修改构造器,使其在被要求创建第二个是实例时,抛出异常。
另外,为了防止每次反序列化时都创建新实例,必须声明所有实例域都是瞬时的,并提供readResolve方法:

private Object readReslove(){
    return INSTANCE;
}

方法三:

public class Elvis{
    INSTANCE;
    ...
}

此方法是实现Singleton的最佳方法。(从java 1.5起可用。)它简洁,提供序列化机制,防止多次实例化。只需编写一个包含单个元素的枚举类型:

第4条:通过私有构造器强化不可实例化的能力

如果需要编写只有静态方法和静态域的类时,这种工具类是不希望被实例化,其实例化也没有意义的,而为了防止编译器添加默认构造器,只要让类包含私有构造器即可:

public class UtilityClass{
    private UtilityClass(){ //私有构造器,防止该类被实例化
        throw new AssertionError(); //创建对象即抛出错误
    }
    ...
}

但这将使得该类不能被子类化,因为没有可以调用的超类构造器。

第5条:避免创建不必要的对象

  1. 除了重用不可变的对象之外,也可以重用那些已知不会被修改的可变对象。

    String s = new String("abcdef");    //语句1,每次执行都创建新String实例
    String s = "abcdef";    //语句2,每次执行都只使用同一个String实例
    

    对于语句1,每次执行都将创建一个新的String实例,这是没必要的,因为“abcdef”本来就是String对象。

  2. 要优化使用基本数据类型而不是装箱基本类型,要当心无意识的自动装箱。

    public static main(String[] args){
        Long sum = 0L;
        for(long i = 0; i < Integer.MAX_VALUE; i++){
            sum += i;   //每次执行都会自动装箱,因为sum的类型是Long而不是long
        }
        System.out.printIn(sum);
    }
    

第6条:清理过期的对象引用

  1. 一个对象被无意识地保存起来,那么垃圾回收机制不仅不会处理该对象,也不会处理被该对象引用的其他对象。对性能造成潜在的重大影响。
  2. 清除过期引用最好的方法是让包含该引用的变量结束其生命周期。一旦程序不用某个对象引用就清空,这是没必要的。
  3. 除了自己管理内存的类(如Stack)外,内存泄露的另一个常见来源是缓存。(可用WeakHashMap。)
  4. 可以使用后台线程(Timer或ScheduledThreadPoolExecutor)或添加新条目时,进行缓存项的清理(如LinkedHashMap类的removeEldestEntry方法)。
  5. 内存泄露的第三个常见来源是监听器和其他回调。确保回调立即被当作垃圾回收的最佳方法是只保存他们的弱引用(weak reference)。

第7条:避免使用终结方法

  1. 终结方法通常是不可预测的,也是很危险的,会导致行为不稳定、降低性能,以及可移植性问题。一般情况下是不必要的。
  2. Java语言规范不仅不保证终结方法会被及时地执行,而且根本就不保证它们会被执行。
  3. 终结方法在不同的JVM平台上的运行表现可能截然不同。
  4. 可用显示的终止方法(如close(),cancel()等结合try-finally结构)来终结类的对象中封装的资源。
  5. “终结方法链”不会被自动执行,子类覆盖超类终结方法就必须手工调用超类终结方法。
  6. 除非作为安全网(对象所有者忘记调用显示终止方法),或则终止非关键的本地资源,否则不要使用终止方法。使用终结方法要记住调用super.finalize()。作为安全网,要记得记录终结方法的非法性(因为这表示客户端代码中的一个Bug)。如果需要把终结方法与公有的非final类关联起来,请考虑使用终结方法守卫者,一确保及时子类的终结方法未能调用super.finalize,该终结方法也会被执行。

    public class Foo{
        //该对象唯一目的是终止外围Foo对象
        private final Object finalizerGuardian = new Object(){
            @override protected void finalize() throws Throwable{
                ...//终结外围Foo对象
            }
        };
        ...
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值