在研究标准Java库及其类时,我不禁注意到其中一些类的方法在我看来几乎与这些类的原因无关。
我正在讨论的方法是,例如Integer#getInteger,它检索某些“系统属性”的值,或System#arraycopy,其目的是由其名称定义。 尽管如此,这两种方法看起来都不合适,特别是第一种方法,由于某种原因,它将系统资源与原始类型的包装类绑定在一起。
从我目前的观点来看,这种方法放置政策看起来违反了基本的OOP设计原则:每个班级必须致力于解决其特定的问题,而不是将自己变成瑞士军刀。 但由于我不认为Java设计师是白痴,我认为决定将这些方法放在原来的位置背后有一些逻辑。如果有人能够解释那个逻辑真正是什么,我将不胜感激。
谢谢!
更新
有些人暗示Java确实有其不合逻辑的东西,这些东西只是动荡过去的残余。我重新提出了我的问题:为什么Java不愿意将其架构缺陷标记为已弃用,因为它不像现有的已弃用功能可能会在任何可观察的未来中断,并且使弃用的东西确实有助于避免在新的时候使用它们创建代码?
答案 0 :(得分:4)
这是一个值得怀疑的好事。我知道更近期的功能(例如泛型,lambda等),在邮件列表上有几个博客和帖子,解释了图书馆制作者的选择。这些内容非常有趣。
在你的情况下,我希望答案不会过时。制作它们的原因很难说。但是这两个类都存在于JDK1.0之后。在那些日子里,编程的质量(特别是Java和OO)可能更低(意味着常见的做法较少,图书馆制作者必须自己发明许多范例)。此外,在这些时候还存在其他限制因素,例如Object
创建费用昂贵。
许多设计笨拙的方法和类现在有了更好的选择。 (参见Date
和包java.time
)
您希望将arraycopy
添加到Arrays
课程,但遗憾的是它不在那里。
理想情况下,原始方法会暂时弃用,然后删除。许多图书馆遵循这一策略。然而,Java对此非常保守,只是弃用了真正不应该使用的东西(例如Thread.stop()
。我不认为由于弃用而在Java中删除了一个方法。这意味着它是公平的很容易将您的软件升级到更新版本的Java,但它的代价是在库中留下一些混乱。
java保持新的JDK / JRE版本与旧的源代码和二进制文件兼容是如此保守,这一事实令人喜爱和讨厌。对于您的业余爱好项目,或者一个小型积极开发的项目,升级到新的JVM,几年后删除已弃用的功能并不太困难。但是不要忘记许多项目没有得到积极开发,或者开发人员很难安全地进行更改,例如因为他们缺乏适当的回归测试。在这些项目中,API的更改需要花费大量时间来遵守,并且存在引入错误的风险。
此外,库通常会尝试支持较旧版本的Java以及较新版本,但在删除方法时,它们会遇到问题。
答案 1 :(得分:1)
整数示例可能只是一个设计决策。如果要隐式将属性解释为Integer,请使用java.lang.Integer。否则,您必须为每个java.lang-Type提供一个getter方法。类似的东西:
对于每种数据类型,您需要一个额外的默认方法: - System.getPropertyAsBoolean(String,boolean) - System.getPropertyAsByte(String,byte) ...
由于java.lang-Types已经有一些强制转换能力(Integer.valueOf(String)),所以我在这里找到一个getProperty方法并不会太惊讶。在交易中方便了一点点破坏原则。
对于System.arraycopy ,我想这是一个取决于操作系统的操作。您可能以非常有效的方式将内存从一个位置复制到另一个位置。如果我想复制这样的数组,我会在java.lang.System
中查找它答案 2 :(得分:0)
“我认为决定放置那些背后有一些逻辑 方法就在哪里。“
虽然这通常是正确的,但我发现,当某些事情发生时,这种假设通常是你误导的地方。
一种语言在不断发展,从有人提出新语言的那天到它过时的那一天。在这些极端之间是语言经历的一些阶段。特别是如果有人在上面花钱并且希望人们使用它,那么在第一次发布之前或之后经常会出现一个非常特殊的阶段:
“我们需要这个工作昨天”阶段。
这就是这样的事情,你有一个几乎完整的语言,但程序员需要做一些事情来展示语言可以做什么,或者特定的应用程序需要一个没有设计成语言的功能。 / p>
那么我们在哪里添加此功能? - 好吧,对那个特定的程序员来说,最重要的是“让它在昨天工作”。
逻辑可能是,这是函数最有意义的地方,因为它不属于任何其他地方,并且它不值得拥有它自己的类。它也可能是这样的:到目前为止,我们从未完成过数组副本,没有使用系统..让我们把arraycopy放在那里,并为每个人节省额外的包括..
很久以后,如果有人愿意清理它,它会被标记为已弃用并被删除..