已弃用的 API 和旧版 API 之间的区别?

发布于 2024-09-02 09:24:18 字数 248 浏览 3 评论 0原文

我正在研究 Java 的 Collection Framework 中的遗留 API,并且了解到 VectorHashTable 等类已被 ArrayList 取代HashMap

然而,它们仍然没有被弃用,并且被视为遗留,本质上,弃用适用于被取代且应该避免的软件功能,因此,我不确定 API 何时被视为遗留以及何时被弃用。

I was studying the legacy API's in the Java's Collection Framework and I learnt that classes such as Vector and HashTable have been superseded by ArrayList and HashMap.

However still they are NOT deprecated, and deemed as legacy when essentially, deprecation is applied to software features that are superseded and should be avoided, so, I am not sure when is a API deemed legacy and when it is deprecated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

你爱我像她 2024-09-09 09:24:18

来自 Sun 官方术语表:

弃用:指不再推荐的类、接口、构造函数、方法或字段,并且可能在未来版本中不再存在。

从如何以及何时弃用指南中:

您可能听说过“自嘲式幽默”这个词,或者是贬低说话者重要性的幽默。已弃用的类或方法就是这样。这已经不重要了。事实上,它是如此不重要,您不应该再使用它,因为它已被取代并且将来可能不复存在。

@Deprecated 注释更进一步并警告危险:

带有 @Deprecated 注释的程序元素是不鼓励程序员使用的,通常是因为它危险,或者因为存在更好的替代方案。

参考文献


请注意,官方术语表没有定义“旧版”的含义。很可能,它可能是乔什·布洛赫(Josh Bloch)使用的一个术语,但没有确切的定义。然而,这意味着永远不应该在新代码中使用遗留类,并且存在更好的替换。

也许使用遗留但未弃用的类的旧代码不需要采取任何操作,因为至少现在,它们不会面临在未来版本中停止存在的危险。

相反,弃用明确警告它们可能不复存在,因此应采取行动迁移到替代品。


来自《Effective Java 第二版》的引述

为了比较这些术语在上下文中的使用方式,这些是书中出现“已弃用”一词的引述:

第 7 项:避免终结器:声称保证终结的唯一方法是 System.runFinalizersOnExit 及其邪恶孪生 Runtime.runFinalizersOnExit。这些方法存在致命缺陷,已被弃用。

第 66 项:同步对共享可变数据的访问:库提供了 Thread.stop 方法,但此方法很久以前就已被弃用,因为它本质上不安全——它的使用可能会导致数据损坏。

第 70 项:文档线程安全System.runFinalizersOnExit 方法是线程敌对的,已被弃用。

第 73 项:避免线程组:它们允许您同时将某些 Thread 原语应用到一堆线程。其中一些原语已被弃用,其余的则很少使用。 [...] 线程组已过时。

相比之下,这些是出现“legacy”一词的引号:

第 23 项:不要在新代码中使用原始类型:提供它们是为了与早于泛型引入的遗留代码兼容和互操作。

第 25 项:优先选择列表而不是数组:擦除允许泛型类型与不使用泛型的遗留代码自由地互操作。

第 29 项:考虑类型安全的异构容器:这些包装器对于跟踪谁将类型错误的元素添加到混合通用代码和旧代码的应用程序中的集合中非常有用。

第 54 项:明智地使用本机方法:它们提供对遗留代码库的访问,而这些代码库又可以提供对遗留数据的访问。 [...] 使用本机方法访问遗留代码也是合法的。 [...] 如果必须使用本机方法来访问低级资源或遗留库,请尽可能少地使用本机代码并对其进行彻底测试。

第 69 项:优先使用并发实用程序而不是等待和通知:虽然您应该始终优先使用并发实用程序而不是 waitnotify,您可能必须维护使用 waitnotify 的旧代码。

这些引用没有经过精心挑选:它们都是书中出现“已弃用”和“遗留”一词的所有实例。 Bloch 的信息在这里很明确:

  • 不推荐使用的方法,例如 Thread.stop,是危险的,根本不应该使用。
  • 另一方面,例如wait/notify可以保留在遗留代码中,但不应该在新代码中使用。

我自己的主观意见

我的解释是,反对某件事就是承认它是一个错误,而且从一开始就不好。另一方面,将某物归类为遗产就是承认它在过去足够好,但它已经达到了其目的,并且对于现在和未来来说不再足够好。

From the official Sun glossary:

deprecation: Refers to a class, interface, constructor, method or field that is no longer recommended, and may cease to exist in a future version.

From the how-and-when to deprecate guide:

You may have heard the term, "self-deprecating humor," or humor that minimizes the speaker's importance. A deprecated class or method is like that. It is no longer important. It is so unimportant, in fact, that you should no longer use it, since it has been superseded and may cease to exist in the future.

The @Deprecated annotation went a step further and warn of danger:

A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists.

References


Note that the official glossary does not define what "legacy" means. In all likelihood, it may be a term that Josh Bloch used without an exact definition. The implication, though, is always that a legacy class should never be used in new code, and better replacement exists.

Perhaps an old code using legacy but non-deprecated class requires no action, since for now at least, they aren't in danger of ceasing to exist in future version.

In contrast, deprecation explicitly warns that they may cease to exist, so action should be taken to migrate to the replacement.


Quotes from Effective Java 2nd Edition

For comparison on how these terms are used in context, these are quotes from the book where the word "deprecated" appears:

Item 7: Avoid finalizers: The only methods that claim to guarantee finalization are System.runFinalizersOnExit and its evil twin Runtime.runFinalizersOnExit. These methods are fatally flawed and have been deprecated.

Item 66: Synchronize access to shared mutable data: The libraries provide the Thread.stop method, but this method was deprecated long ago because it's inherently unsafe -- its use can result in data corruption.

Item 70: Document thread safety: The System.runFinalizersOnExit method is thread-hostile and has been deprecated.

Item 73: Avoid thread groups: They allow you to apply certain Thread primitives to a bunch of threads at once. Several of these primitives have been deprecated, and the remainder are infrequently used. [...] thread groups are obsolete.

By contrast, these are the quotes where the word "legacy" appears:

Item 23: Don't use raw types in new code: They are provided for compatibility and interoperability with legacy code that predates the introduction of generics.

Item 25: Prefer lists to arrays: Erasure is what allows generic types to interoperate freely with legacy code that does not use generics.

Item 29: Consider typesafe heterogeneous containers: These wrappers are useful for tracking down who adds an incorrectly typed element to a collection in an application that mixes generic and legacy code.

Item 54: Use native methods judiciously: They provide access to libraries of legacy code, which could in turn provide access to legacy data. [...] It is also legitimate to use native methods to access legacy code. [...] If you must use native methods to access low-level resources or legacy libraries, use as little native code as possible and test it thoroughly.

Item 69: Prefer concurrency utilities to wait and notify: While you should always use the concurrency utilities in preference to wait and notify, you might have to maintain legacy code that uses wait and notify.

These quotes were not carefully selected: they're ALL instances where the word "deprecated" and "legacy" appear in the book. Bloch's message is clear here:

  • Deprecated methods, e.g. Thread.stop, are dangerous, and should never be used at all.
  • On the other hand, e.g. wait/notify can stay in legacy code, but should not be used in new code.

My own subjective opinion

My interpretation is that deprecating something is admitting that it is a mistake, and was never good to begin with. On the other hand, classifying that something is a legacy is admitting that it was good enough in the past, but it has served its purpose and is no longer good enough for the present and the future.

别理我 2024-09-09 09:24:18

一种常见的解释是,Deprecated 意味着它将在不久的将来被删除,Legacy 意味着它将出于向后兼容性或其他原因而保留。

两者都意味着新代码不应使用它们。

对于 JDK,甚至不推荐使用的代码也会保留,因为向后兼容性对于 Java JDK 非常重要。

A common interpretation is that Deprecated means that it will be removed in the near future, and Legacy means that it will remain for backwards compatibility or other reasons.

Both mean that they shouldn't be used by new code.

In the case of the JDK even Deprecated code will remain, since backwards compatibility is very important for the Java JDK.

残龙傲雪 2024-09-09 09:24:18

弃用通常表示打算在将来的某个时候删除该功能,而遗留只是意味着如果可能的话,不应在新代码中使用它(尽管出于互操作原因甚至可能需要)。

Deprecation often denotes that there is an intention to remove the functionality at some point in the future, whereas legacy just implies it shouldn't be used in new code if at all possible (though may even then be needed for interop reasons).

情定在深秋 2024-09-09 09:24:18

弃用意味着它不好并且不应该使用 - File.toURL() 就是一个很好的例子,因为它不会从路径中带有空格的文件创建正确的 URL。它根本没有做它应该做的事情,但是由于现有代码可能使用变通办法,如果修复了错误,这些变通办法就会中断。

遗留只是意味着它已经过时了,并且有一些方法可以做一些通常但不一定更好的事情。 Vector 是一个很好的例子 - 它是一个 List 实现,但它仍然有一些来自 Collections API 之前的丑陋的废话(即 List >) 被设计。它也是同步的,这意味着即使在单线程场景中使用它也必须支付同步费用(除了某些VM很聪明的情况)。如果您想要一个支持数组的列表实现,ArrayList 会更好,因为它是非同步的;而当您想要一个同步列表时,Collections.synchronizedList 会更灵活,因为它是一个包装器,可以与所有列表实现(链接列表、Arrays.asList(T...) 中的列表等)一起使用。但是,如果您确实碰巧想要一个同步的、支持数组的列表实现,那么Vector就可以了。

Deprecation means that it's bad and shouldn't be used - File.toURL() is a prime example, since it doesn't create correct URLs from files with spaces in the path. It's simply not doing what it should, but since existing code might be using workarounds which would break if the bug was fixed

Legacy just means that it's old and there are ways of doing something which are generally, but not necessarily, better. Vector is a good example - it is a List implementation, but it's still got some ugly crap from the days before the Collections API (i.e., List) was designed. It is also synchronized, which means that you have to pay the synchronization fee even when using it in a single-threaded scenario (except for in some situations where the VM is clever). ArrayList is better if you want an array-backed list implementation since it's unsynchronized, and Collections.synchronizedList is more flexible when you want a synchronized list since it's a wrapper which can be used with all list implementations (linked lists, lists from Arrays.asList(T...), etc). However, if you do happen to want a synchronized, array-backed list implementation, then Vector is fine.

迷途知返 2024-09-09 09:24:18

我的解释是,遗留代码只是有更新的对应代码,可以更好地完成工作。但是,它将继续获得错误修复和其他支持。另一方面,已弃用的代码不受支持,也不会收到专门的错误修复。

My interpretation is that Legacy code simply has newer counterparts that do the job better. It will, however, continue to receive bug fixes and other support. Deprecated code, on the other hand, is unsupported and won't receive dedicated bug fixes.

孤独患者 2024-09-09 09:24:18

Deprecated 注释给出了正式的已弃用的 API 的定义。我认为遗留类不存在正式的定义。两者实际上都意味着该类不应在新代码中使用。

The Deprecated annotation gives a formal definition of a deprecated API. I don't think that a formal definition for legacy classes exists. Both actually mean that the class shouldn't be used in new code.

眼泪也成诗 2024-09-09 09:24:18

我有一个建议 - 遗留是指过去编写的代码,已弃用是指不再使用它的建议。您仍然可以使用已弃用的 api,但您无法编写遗留代码,因为您现在正在编写它。
只是恕我直言

I have a suggestion - legacy refers to code that was written in the past, deprecated refers to the advice not to use it anymore. You can still use deprecated api, but you can't write legacy code, cuz you're writing it right now.
Just IMHO

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文