11

我最近正在浏览一个 Netflix 开源项目

在那里,我发现了最终类和私有构造函数的使用。我完全意识到

  1. final 是为了避免继承
  2. private 是禁止实例化

但我只是想知道为什么它们都一起使用。虽然方法是静态的,所以我们可以在不实例化的情况下使用它们,但仍然渴望了解其背后的设计原理。

4

2 回答 2

8

使用此代码,您将拥有此功能

  • 不允许任何人子类 ( extends) 你的类
  • 不允许实例化你的类
  • 使变量或类最终提高性能(不多,但它确实并用作大型项目中的常见做法会有所作为)

在这种情况下,我看不到单例模式来获取实例,因此,恕我直言,您正在寻找 Netflix API 中的帮助程序/实用程序类,开发团队使用一些标准实践来确保用户使用他们的类正确的方法:

StaticFinalClassExample.methodYouWantToCall();

另外,查看您链接的课程:

/**
 * This class consists exclusively of static methods that help verify the compliance of OP1A-conformant....
 */

和:

//to prevent instantiation
private IMFConstraints()
{}

添加在:

如果您想了解更多信息,请查看Joshua BlochItem 4Effective Java(第 2 版)

第 4 条:使用私有构造函数强制执行不可实例化

有时您会想要编写一个只是一组静态方法和静态字段的类。这样的类名声不好,因为有些人滥用它们以避免从对象的角度思考,但它们确实有有效的用途。

  • 它们可用于以 或 的方式对原始值或数组的相关方法进行java.lang.Math分组java.util.Arrays
  • 它们还可以用于对实现特定接口的对象的静态方法(包括工厂方法(第 1 项))进行分组,以java.util.Collections.
  • 最后,它们可用于对final类上的方法进行分组,而不是扩展类。

这样的实用程序类不是为了实例化而设计的:实例是无意义的。然而,在没有显式构造函数的情况下,编译器提供了一个公共的、无参数的默认构造函数。对于用户而言,此构造函数与其他构造函数没有区别。在已发布的 API 中无意中看到可实例化的类并不少见。

试图通过使类抽象来强制执行不可实例化是行不通的。该类可以被子类化并且子类可以被实例化。此外,它误导用户认为该类是为继承而设计的(第 17 条)。

但是,有一个简单的习惯用法可以确保不可实例化。仅当类不包含显式构造函数时才会生成默认构造函数,因此可以通过包含私有构造函数使类不可实例化。

于 2016-08-22T12:00:55.243 回答
0

该类由static所谓的“实用程序”方法组成,因此您不需要它的实例,而且尝试获取它的实例是错误的。该类是最终类,因此客户端开发人员无法选择继续扩展该类,因为这与原始类的意图背道而驰。

私有构造函数基本上有两种用途:在您想要限制创建的类的情况下严格控制实例化(例如,如果它需要大量资源)。在第一种情况下,您必须提供static为客户端创建对象的工厂方法。IE:

public static IMFConstraints getInstance()

另一种情况是创建实例永远无效。在这种情况下,您提供static在类本身上调用的方法。IE:

public static void checkIMFCompliance(List<PartitionPack> partitionPacks)

您可以像这样调用上述方法:

// your cool client code here...
IMFConstraints.checkIMFCompliance(myPartitionPacks);
// more of your awesome code...

您链接的课程是后一种情况。

于 2016-08-22T12:01:37.007 回答