Effective_java边读边总结

13条:使类和成员的可访问性最小化:

1、如果一个子类覆盖了父类的一个方法,子类中的方法访问级别必须高于父类中方法的访问级别,这样可以确保任何使用父类的实例的地方也都可以使用子类的实例:

eg:

父类:

public class PerSon {
    protected  void print(){
        System.out.println(" this is a person");
    }
}

子类:

public class User extends PerSon {
   //这里覆盖的print方法的访问级别只能是protected或者public
    @Override
    public void print() {
        super.print();
    }
}

java的访问控制级别:

private:私有的,只有在声明该成员的内部使用;

default:缺省时的默认访问级别,只有同一个包下面的类才能访问;

protected:受保护的访问级别,2种情况下可以访问:1、同一个包下面可以访问;2、继承该类的子类可以访问;

public:公开的,顾名思义没什么限制,所有包下的所有类都可以访问;

注:我们将protected和public称作导出包的api;

2、实例域绝不能是共有的,这样就破坏了数据的封装型;

14条:在共有类中使用访问方法而非共有域:

对于包级私有的类,或者是私有的嵌套类,直接暴露数据域也并没有问题;

共有类永远不应该暴露可变的域,暴露不可变的域虽然还是有问题,但是伤害小点;

15条:使可变类最小化:

使类成为不可变的五个条件:

1、不要提供任何修改对象状态的方法;

2、保证类不会被拓展,一般将类修饰成final

3、使所有的域都是final的;

4、使所有的域都是私有的;

5、确保对于任何可变组件的互斥访问;

不可变对象比较简单,并且是线程安全的,无需手动同步,所以不可变对象可以被自由的共享;

16:符合优于继承

17:要么为继承而设计,并提供说明文档,要么就禁止继承;

父类构造器觉不能调用可被覆盖的方法;

eg:

public class Super {

    public  Super(){
        overide();
    }

    public void overide(){

    }
}

子类:

public class Sup extends Super {

    private Date date;

    Sup(){
     date = new Date();
    }

    @Override
    public void overide() {
        System.out.println(date);
    }

    public static void main(String[] args) {
        Sup sup = new Sup();
        sup.overide();
    }
}

我们可能期望的是打印2次日期,但是事实是第一次打印的是null,因为调用子类构造器之前会先调用父类Super的构造器,父类的构造器会调用Sup子类的overide覆盖方法,此时子类Sup的构造方法还没有执行,所以date对象是个null对象;

18:接口优于抽象类:

现有类可以很容易被更新,以实现新的接口;

接口是定义mixin的理想选择;

接口允许我们构造非层次结构的类型框架;

public class TestAbstract {

    static List<Integer> intArrayList(final  int [] array){
        if (array == null)
            throw  new NullPointerException();
        return new AbstractList<Integer> (){

            @Override
            public int size() {
                return array.length;
            }

            @Override
            public Integer get(int index) {
                return array[index];
            }
            @Override
            public Integer set(int i, Integer value){
                Integer oldval = array[i];
                array[i] = value;
                return oldval;
            }
        };

    }

    public static void main(String[] args) {
        int [] array = new int[]{1,2,3};
        List  list = intArrayList(array);
        System.out.println(list.get(2));
    }
}

如果无法拓展这个类,那也可以自己接实现这个接口,实现这个接口的类可以把对于接口方法的调用,转发到一个内部私有类实例,这个内部私有类拓展了骨架实现类,就像上面这样的实现,这种方法被称作模拟多重继承,它实现了多重继承的优点,同时又避免了单继承的缺点;

19:接口只用于定义类型:

常量接口不值得效仿:

public interface ConstantInterface {
    
    public static final  int CONSTANT = 0;
}

这是一个反面的例子;

20:类层次优于标签类;

21:用函数对象表示策略;

22:优先考虑静态成员类(静态类内部类);

内部类分为四种:静态内部类、成员内部类、局部内部类、匿名内部类

第五章:泛型

23:不要在新代码中使用原生态类型:

24:消除非受检警告:

尽量消除非受检警告,因为每一条非受检警告都包含一条ClassCastException,如果能够确定某条非受检警告是类型安全的,那么可以使用@SuppressWarnings("unchecked")来忽略这条警告,这个注解可以用在类,方法、局部变量上,我们应该让在尽可能让@SuppressWarnings("unchecked")的影响范围最小;

25:列表优于数组:

数组不能使用泛型

26:优先考虑泛型:

27:优先考虑泛型方法:

猜你喜欢

转载自blog.csdn.net/chengkui1990/article/details/81353312