代码之家  ›  专栏  ›  技术社区  ›  Roalt

为什么java.util.scanner类声明为“final”?

  •  5
  • Roalt  · 技术社区  · 15 年前

    我使用 Scanner class 用于读取多个类似文件。我想扩展一下,以确保他们都使用相同的 分隔符 我也可以添加一些方法,比如 skipuntilYoufind(在这里串起来) 所有这些对他们都有效。

    我可以创建一个包含它们的实用程序类,或者将scanner类作为变量嵌入到另一个类中,但这更麻烦。

    我找到了 some reasons 声明一个类的最终结果,但是为什么要在这里完成呢?

    3 回复  |  直到 11 年前
        1
  •  4
  •   Andrei Fierbinteanu    15 年前

    可能是因为扩展它和重写它的一些方法可能会破坏它。使重写方法更容易暴露于许多内部工作中,因此,如果将来它们决定更改这些方法(出于性能或其他原因),那么它们在不破坏扩展方法的所有类的情况下更改类将更加困难。

    例如,在类中考虑以下方法:

    public boolean nextBoolean()  {
        clearCaches();
        return Boolean.parseBoolean(next(boolPattern()));
    }
    

    假设你想改写这个,因为你想让“棒极了”的值变成“真的”布尔值(不管是什么原因)。如果覆盖它,就不能调用super.nextBoolean(),因为它将使用默认逻辑使用下一个令牌。但如果不调用super.nextBoolean(),则不会调用ClearCaches(),可能会破坏其他未覆盖的方法。不能调用ClearCaches(),因为它是私有的。如果他们让它受到保护,但随后意识到这会导致性能问题,并且想要一个不再清除缓存的新实现,那么他们可能会破坏覆盖的实现,而这仍然会调用它。

    所以基本上是这样的,他们可以很容易地改变类中隐藏的部分,这是非常复杂的,并且保护你不被破坏的儿童类(或者一个很容易被破坏的类)。

        2
  •  1
  •   lisak    15 年前

    我想是因为安全原因。这个类读取用户输入,这样有恶意的人就可以扩展它,修改它的行为,然后你就完蛋了。如果它是最终的,对于坏人来说不是那么容易,因为如果他制作了自己的扫描仪(而不是java. U.L.S扫描仪),多态性的原理就会被打破。看吧,坏人足够聪明,可以写一个机器人/脚本,在远程服务器上自动完成这项工作…他甚至可以通过在已编译的应用程序中动态加载类来实现这一点。

        3
  •  0
  •   Eran Harel    15 年前

    我认为你提供的链接可以解释这一切。

    在您的情况下,似乎您应该更喜欢组合而不是继承。您正在创建一个具有一些预定义行为的实用程序,它可以隐藏扫描器类的某些(或全部)详细信息。

    我见过许多使用继承来改变行为的实现。最终结果通常是一个整体设计,在某些情况下,是一个破坏的契约和/或破坏的行为。