6

ImmutableList文档说

虽然这个类不是最终的,但它不能被子类化,因为它没有公共或受保护的构造函数。

我知道这有点牵强,但是可以创建一个可变的ImmutableListin com.google.common.collectpackage 子类(因为它的构造函数不是私有的,而是包私有的)。从那时起,没有任何人得到对 an 的引用ImmutableList可以确定它确实是不可变的。这不是破坏目的ImmutableList吗?

4

2 回答 2

5

归根结底,Guava 只是你正在执行的一堆二进制文件。你可以用它做任何你想做的事情,包括违反代码提供的合同。

你可以:

  • 运行破坏 Guava 的自定义 JVM
  • 运行单独的应用程序并操作 JVM 的物理内存并破坏 Guava
  • 操作 Guava 字节码并破坏 Guava
  • 配置类加载器以加载其他字节码并破坏 Guava
  • 打电话sun.misc.Unsafe打破番石榴
  • 使用反射来破坏 Guava
  • 滥用包层次结构并破坏 Guava

仅举几个。这些都不是Guava独有的,Java 独有的。这是你的机器,你应该能够做这些事情。当然,你能做什么和你应该做什么是完全不同的事情。以任何这些方式滥用 Java 都会给你和任何试图运行你的代码的人带来问题。

Java 类型系统,包括可见性限制,不是警察。它的存在是为了帮助您编写易于使用的高质量代码。Guava 利用 Java 的记录行为为您提供更多工具,使您能够编写更容易使用的质量更高的代码。如果您选择破坏工具,那是您的特权。但不要指望任何人想要使用您的代码。


要具体解决这一点:

可以创建一个可变的ImmutableListin com.google.common.collectpackage 子类(因为它的构造函数不是私有的,而是包私有的)。

您可以以几乎相同的方式将私有构造函数类操作为可变的,而无需做太多工作。正如我上面提到的,滥用包层次结构只是您根本不应该做的许多事情之一。如果您不相信一段第三方代码在这方面表现良好,则不应使用它。

于 2015-07-28T04:45:18.980 回答
3

即使您扩展ImmutableList,您也无法使其可变,因为它的所有 mutator 方法都是最终的,就像这个:

  public final void add(int index, E element) {
    throw new UnsupportedOperationException();
  }

并且它的迭代器返回UnmodifiableIterator其 remove 方法也是最终的

于 2013-07-30T10:10:28.720 回答