notebook notebook
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)

学习笔记

啦啦啦,向太阳~
首页
  • 计算机网络
  • 计算机系统
  • 数据结构与算法
  • 计算机专业课
  • 设计模式
  • 前端 (opens new window)
  • Java 开发
  • Python 开发
  • Golang 开发
  • Git
  • 软件设计与架构
  • 大数据与分布式系统
  • 常见开发工具

    • Nginx
  • 爬虫
  • Python 数据分析
  • 数据仓库
  • 中间件

    • MySQL
    • Redis
    • Elasticsearch
    • Kafka
  • 深度学习
  • 机器学习
  • 知识图谱
  • 图神经网络
  • 应用安全
  • 渗透测试
  • Linux
  • 云原生
面试
  • 收藏
  • paper 好句
GitHub (opens new window)
  • Java开发

    • My

    • Posts

    • Java SE

      • 黑马课程

      • 专栏:Java 核心技术面试精讲

      • Effective Java

        • Creating and Destroying Objects
          • 2. Creating and Destroying Objects
            • Item 1: Consider static factory methods instead of constructors
            • Item 2: Consider a builder when faced with many constructor parameters
            • Item 3: Enforce the singleton property with a private constructor or an enum type
            • Item 4: Enforce noninstantiability with a private constructor
            • Item 5: Prefer dependency injection to hardwiring resources
            • Item 6: Avoid creating unnecessary objects
            • Item 7: Eliminate obsolete object references
            • Item 8: Avoid finalizers and cleaners
            • Item 9: Prefer try-with-resources to try-finally
        • Methods Common to All Objects
    • Java 并发编程

    • JVM

    • JDBC

    • Java Web

    • Spring 与 SpringMVC

    • Spring Boot

    • Spring Cloud

    • Spring Security

    • Netty

    • MyBatis

  • Python开发

  • Golang开发

  • Git

  • 软件设计与架构

  • 大数据与分布式系统

  • 区块链

  • Nginx

  • 开发
  • Java开发
  • Java SE
  • Effective Java
yubin
2023-08-12
目录

Creating and Destroying Objects

# 2. Creating and Destroying Objects

# Item 1: Consider static factory methods instead of constructors

编写为一个 class 实例化 instance 的方式通常有两种:

  • 提供一个 public constructor
  • 提供一个 public static factory method

两者各有优缺点,根据不同的场景,选择一个合适的实例化方法。

# Item 2: Consider a builder when faced with many constructor parameters

静态工厂和构造器都无法很好地适应存在大量可选参数的情况。这一节介绍了三种用来生成这种对象的模式,并进行比较,体现了 Builder 模式在这种情况下的优点。

三种用来构建存在大量可选参数的模式:

  1. telescoping constructor pattern:先写一个有所有必选参数的 ctor,然后写一个带所有参数和一个可选参数的 ctor,再写一个带所有参数和两个可选参数的 ctor,....,直至在一个 ctor 里有所有的可选参数。
  2. JavaBeans pattern:ctor 是无参的,调用 ctor 后再通过各 setter 方法来设置各个成员变量。
  3. Builder pattern:在 class 内写一个 Builder 类,并通过它的 build() 方法来生成我们需要的实例。

Builder pattern 对于调用者来说可读性更好,并很好地与类的继承体系进行融合,如何编写出 Builder 可以参考原文。

这部分原文讲的很好,并涉及了如何编写类的泛型。

# Item 3: Enforce the singleton property with a private constructor or an enum type

这节主要介绍了在实现 singleton 的常见方法和注意事项。

两种常见方式:

  • 方式 1:有一个 public static final 的属性 INSTANCE,并通过自身的私有构造器来初始化为单例。
  • 方式 2:有一个 private static final 的属性 INSTANCE 并被私有构造器初始化,然后写一个静态工厂 getInstance() 用来获得这个单例。

其实还经常使用“双重检查锁”的方法来实现单例。

实现单例的注意点:

  • 使用者也许会通过反射来获取私有构造器进而破坏单例。
    • 预防方法:让 ctor 在第二次被调用时抛出异常
  • 对 singleton 序列化再反序列化后,可以获得新的实例,从而破坏了单例
    • 预防方法:修改 readResolve() 方法,让其也直接返回已有的单例

之后原文重点介绍了通过声明 a single-element enum 的方式来实现单例:

public enum Elvis {
    INSTANCE;

    public void customMethod() {
        ...
    }
}
1
2
3
4
5
6
7

这种方式可以抵御因序列化、反射而导致的破坏单例的攻击,但无法让你的 class 去继承一个非 Enum 的 superclass。如果可以,a single-element enum type is often the best way to implement a singleton。

# Item 4: Enforce noninstantiability with a private constructor

往往我们会写一些 utility classes,这种 class 里面是一堆 static methods 和 static fields,他们不被设计为可以实例化的。

然而 Java 编译器会默认为 class 生成 public、parameterless 的 ctor,为了防止有人将其实例化,我们可以为这种类编写一个显式的 private 无参构造器:

// Noninstantiable utility class
public class UtilityClass {
    // Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
    ... // Remainder omitted
}
1
2
3
4
5
6
7
8

这样就不会有人能够实例化或继承这个类了。

# Item 5: Prefer dependency injection to hardwiring resources

依赖注入就是在创建这个类时将它所依赖的其他类传递(pass)进去。区别于依赖注入的方式是这个类在内部把自己依赖的其他类给创建出来,而不是通过外界传入进去的方式。

最简单的注入方法就是在构造器方法中声明它所依赖的类,并在调用构造器实例化时完成依赖的注入。如下:




 




public class SpellChecker {
    private final Lexion dictionary;

    public SpellChecker(Lexicon dictionary) {
        this.dictionary = Objects.requireNonNull(dictionary);
    }
}
1
2
3
4
5
6
7

这里的 dependency injection 不要局限于 Spring 的依赖注入。

# Item 6: Avoid creating unnecessary objects

复用一个 single object 是比每次创建一个新的 functionally equivalent object 更好的。

  • static factory methods 能帮助我们避免创建不必要的实例。
  • 很多你看不见的地方会偷偷创建实例,比如 String 的 match() 方法内部会每次调用时创建一个 Pattern 实例用于正则匹配,而且用一次后就扔。
  • 为了节省一两个对象的创建开销而使用惰性初始化技术是得不偿失的。
  • 不可变类是可以安全地复用的。
  • 为了避免 object 的创建而维护一个你自己的 object pool 是得不偿失的。

# Item 7: Eliminate obsolete object references

Null out references once they become obsolete.

但是,Nulling out object references should be the exception rather than the norm. 消除引用的最好方式是让引用这个 object 的变量自然地 fall out of scope。

Cache 的维护容易出现内存泄漏。如果你的 cache entry 的生命周期取决于 key 的外部引用,而不取决于 value,那使用 WeakHashMap 来实现 cache 是一个很好地选择。

# Item 8: Avoid finalizers and cleaners

finalizer 和 cleaner 都不是啥好东西,如果不是很了解他们的行为,那都不要用。

如果你需要在实例使用完后关闭一些资源,实现 AutoCloseable 是更好的选择。

# Item 9: Prefer try-with-resources to try-finally

关闭资源的最好编码风格是 try-with-resources 的方式,尤其是需要关闭多个资源时。

// try-with-resources on multiple resources - short and sweet
static void copy(String src, String dst) throws IOException {
    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        byte[] buf = new byte[BUFFER_SIZE];
        int n;
        while ((n = in.read(buf)) >= 0)
            out.write(buf, 0, n);
    }
}
1
2
3
4
5
6
7
8
9
10
编辑 (opens new window)
上次更新: 2023/11/12, 11:03:40
Java 基础 2
Methods Common to All Objects

← Java 基础 2 Methods Common to All Objects→

最近更新
01
Deep Reinforcement Learning
10-03
02
误删数据后怎么办
04-06
03
MySQL 一主多从
03-22
更多文章>
Theme by Vdoing | Copyright © 2021-2024 yubincloud | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×