为什么 java.util.Scanner 类被声明为“final”?
我使用 Scanner 类 来读取多个类似的文件。我想扩展它以确保它们都使用相同的分隔符,并且我还可以添加诸如skipUntilYouFind(String thisHere)之类的方法,这些方法对它们都有效。
我可以创建一个包含它们的实用程序类,或者将扫描仪类作为变量嵌入到另一个类中,但这更麻烦。
我发现一些理由声明一个类为final,但是为什么要在这里完成?
I use the Scanner class for reading multiple similar files. I would like to extend it to make sure they all use the same delimiter and I can also add methods like skipUntilYouFind(String thisHere) that all valid for them all.
I can make a utility-class that contain them, or embed the Scanner Class as a variable inside another class but this is more cumbersome.
I have found some reasons to declare a class final, but why is it done here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可能是因为扩展它并覆盖它的一些方法可能会破坏它。并且使覆盖方法变得更容易会暴露大部分内部工作原理,因此,如果将来他们决定更改这些方法(出于性能或其他原因),那么他们将更难在不破坏所有类的情况下更改类从而扩展它。
例如,考虑类中的以下方法:
假设您想要覆盖此方法,因为您想让“awesome”评估为“true”布尔值(无论出于何种原因)。如果覆盖它,则无法调用 super.nextBoolean(),因为这将使用默认逻辑消耗下一个标记。但如果不调用 super.nextBoolean(),则不会调用clearCaches(),这可能会破坏其他未覆盖的方法。您不能调用clearCaches(),因为它是私有的。如果他们对其进行保护,但随后意识到它会导致性能问题,并且想要一个不再清除缓存的新实现,那么他们可能会破坏您覆盖的实现,而该实现仍然会调用它。
所以基本上,他们可以轻松地更改类中非常复杂的隐藏部分,并保护您免于创建损坏的子类(或很容易被损坏的类)。
Probably because extending it and overwriting some of it's methods would probably break it. And making it easier to overwrite methods would expose to much of the inner workings, so if in the future they decide to change those (for performance or some other reasons), it would be harder for them to change the class without breaking all the classes that extend it.
For example, consider the following method in the class:
Say you want to overwrite this because you want to make 'awesome' evaluate to a 'true' boolean (for whatever reason). If you overwrite it, you can't call super.nextBoolean(), since that would consume the next token using the default logic. But if you don't call super.nextBoolean(), clearCaches() won't be called, possibly breaking the other not overwritten methods. You can't call clearCaches() because it's private. If they made it protected, but then realized that it's causing a performance problem, and wanted a new implementation that doesn't clear caches anymore, then they might break your overwritten implementation which would still be calling that.
So basically it's so they can easily change the hidden parts inside the class, which are quite complex, and protecting you from making a broken child class (or a class that could be easily be broken).
我认为这是出于安全原因。这个类读取用户输入,这样恶意的人就可以扩展它,修改它的行为,然后你就会被搞砸了。如果是最终的,对于坏人来说就没那么容易了,因为如果他制作自己类型的Scanner(而不是java.util.Scanner),多态性的原则就会被打破。看到坏人可以足够聪明地编写一个机器人/脚本,在远程服务器上自动执行此操作......他甚至可以通过编译应用程序中的动态类加载来完成此操作。
I suppose it is due to security reasons. This class reads user input, so that someone with bad intentions could extend it, modify it's behavior and you'd be screwed. If it is final, it is not that easy for the bad guy, because if he makes his own type of Scanner (not java.util.Scanner), the principles of Polymorphism would be broken. See the bad guy can be smart enough to write a bot/script which does this automatically on remote servers... He can even do it by dynamic classloading in compiled application.
我认为您提供的链接已经解释了一切。
就您而言,无论如何您似乎应该更喜欢组合而不是继承。您正在创建一个具有某些预定义行为的实用程序,并且可以隐藏 Scanner 类的部分(或全部)详细信息。
我见过许多使用继承来改变行为的实现。最终结果通常是整体设计,在某些情况下,会破坏合同和/或破坏行为。
I think that the link you provided explains it all.
In your case it seems like you should prefer composition instead of inheritance anyway. You are creating a utility that has some predefined behavior, and that can hide some (or all) of the details of the Scanner class.
I've seen many implementations that used inheritance in order to change a behavior. The end result was usually a monolithic design, and in some cases, a broken contract, and/or broken behavior.