• 《Effective Java 2nd》第4章 类和接口


    目录

    第4章 类和接口

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

    尽可能使每个类或者成员不被外界访问。提供尽可能小的访问级别。

    final维持字段不可变性,字段要么是基本类型的、要么是指向不可变对象的引用。

    如果final包含可变对象的引用,虽然引用不能被修改,但是引用对象的内部却可以被修改。

    注意:长度非0的数组总是可变的。

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

    第15条:使可变性最小化

    讲了不可变类的相关内容。

    不可变类:实例不能被修改的类。实例化后,实例中包含的内部信息在整个生命周期中固定不变。

    如何使类不可变

    1)不提供任何修改对象状态的方法

    2)保证类不会被扩展。如将类声明为final

    3)使所有的域都是final的

    4)所有的域都是私有的

    5)对任何可变域(指指向可变对象的域),使用保护性拷贝技术

    不可变对象的好处:线程安全,可以自由共享

    不可变类的唯一缺点:每个不同的值都要有一个单独的对象,比如String s = ”aaa", String s2 = "bbb"。

    因不可变类的缺点,可以提供一个可变配套类,比如对String来说有StringBuilder

    第16条:复合优先于继承

    这里的继承指的是一个类扩展另一个类的时候,不含接口继承(类实现接口、接口实现接口)。

    只有当两个类A和B,两者之间确实存在is a关系的时候,才适合用继承。问自己:每个B都是A吗?

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

    如果某个类是为继承而设计的,在类文档中应该明确描述覆盖每个方法所带来的影响。

    第18条:接口优先于抽象类

    接口和抽象类区别

    1)抽象类允许包含某些方法的实现,接口不允许。

    2)实现抽象类,类必须成为抽象类的子类。但是,任何一个类均可实现一个接口,不管这个类位于类继承层次的哪个位置。

    接口的好处:

    1)现有类很容易通过实现新的接口,实现新的功能,不管这个类位于类继承层次的哪个位置。

    2)接口是定义mixin类型的理想原则。

    mixin类型:指类除了实现它的基本功能外,还可以实现mixin类型,以表明它提供了某种可供选择的功能。

    举例:Comparable是mixin接口,某个类实现后代表具备排序功能。

    3)类允许我们构造非层次接口的类型框架。

    举例:singer接口代表歌唱家,songwriter接口代表作曲家,我们完全可以声明一个SingerSongwriter接口扩展上面两个接口,代表同时歌唱家也是作曲家。

    接口不允许含方法的实现。但是可提供个抽象的骨架实现类。接口用于定义类型,但是骨架实现类用于接口接口实现相关工作。

    举例:集合框架中的AbstractCollection、AbstractSet等都是骨架实现类。

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

    讲了不要使用常量接口。常量接口类似于下面。

    public interface XXXXContants {
      static final double XXXXXX = 1.1222;
      static final double YYYYYY = 1.3222;
    }

    常量接口的坏处:在版本迭代时,某个类不再使用这些常量了,仍必须实现这个接口,以确保二进制兼容性。

    如何定义常量。

    1)常量与某个类或接口紧密相关,定义在这个类后接口中。

    举例:Integer中的常量MIN_VALUE

    2)使用枚举类型

    3)使用常量工具类。

    第20条:类层次优于标签类

    第21条:用函数对象表示策略

    Java中没有函数指针,但是可以用对象引用实现同样的功能,这样的实例称为函数对象,举例:Comparator类定义了排序策略。

    第22条:优先考虑静态成员类

    讲了嵌套类,主要是各种内部类的使用场景。

    嵌套类有4种:

    1)内部类:静态内部类、非静态内部类、匿名内部类

    2)局部类

    静态内部类

    静态内部类常见用法是用作辅助类。举例:Calculator内部声明一个静态枚举类Operation用于表示计算器支持的各种操作。Calculator.Operation.PLUS,Calculator.Operation.MINUS。

    私有静态内部类的常见用法是用来代表外部类所代表的对象的组件。举例:Map的Entry。

    非静态内部类

    非静态内部类的常见用法是定义一个Adapter。举例:Map接口使用非静态内部类来实现集合视图(collection view),如keySet、entrySet等。

    静态内部类和非静态内部类的区别

    1)静态内部类可看做是普通的类,只是碰巧声明在另一个类的内部。可以脱离外部类的实例独立存在。

    2)非静态内部类的每个实例都与外部类的一个实例向关联,当非静态内部类被创建时,这种联系建立起来。

    匿名内部类

    匿名内部类常见用法

    1)创建函数对象。举例:排序时,创建匿名Comparator实例,传递给sort方法。

    2)创建过程对象。举例:Runnable、Thread

    局部类

    在任何可声明局部变量的地方,都可声明局部类。

  • 相关阅读:
    Spring杂谈 | 什么是ObjectFactory?什么是ObjectProvider?
    一次相亲经历,我彻底搞懂了什么叫阻塞非阻塞,同步异步
    Spring杂谈 | 你真的了解泛型吗?从java的Type到Spring的ResolvableType
    Spring官网阅读(十二)ApplicationContext详解(中)
    Spring官网阅读(十一)ApplicationContext详细介绍(上)
    Spring官网阅读(十)Spring中Bean的生命周期(下)
    Spring官网阅读(九)Spring中Bean的生命周期(上)
    influxDB 0.9 C# 读写类
    使用HAProxy实现sql server读库的负载均衡
    influxdb基本操作
  • 原文地址:https://www.cnblogs.com/yeyang/p/10461301.html
Copyright © 2020-2023  润新知