I have stumbled upon Hashing class from com.google.common.hash package.
Intellij IDEA shows following warning if I am using functions of that class:
The class itself is annotated with #Beta annotation:
The description of #Beta annotation says:
Signifies that a public API (public class, method or field) is subject to incompatible changes, or even removal, in a future release. An API bearing this annotation is exempt from any compatibility guarantees made by its containing library. Note that the presence of this annotation implies nothing about the quality or performance of the API ...
So the implementation of the API is fine and stable?
... in question, only the fact that it is not "API-frozen."
It is generally safe for applications to depend on beta APIs, at the cost of some extra work ...
Which kind of extra work?
... during upgrades. However it is generally inadvisable for libraries (which get included on users' CLASSPATHs, outside the library developers' control) to do so.
The question is whether it is safe / stable to use mentioned class and its functionality? What is the tradeoff while using a beta API?
The implementaion of the API is fine, you can rely on that since it is an extensively used library from google.
As for stability - you can do a little research here and compare a couple of versions of this API a year apart. Let's say, 23.0 versus 27.0-jre
https://google.github.io/guava/releases/23.0/api/docs/com/google/common/hash/Hashing.html
https://google.github.io/guava/releases/27.0-jre/api/docs/com/google/common/hash/Hashing.html
If you do a diff, the API's from different years (2017 versus 2018) are exactly the same.
Therefore, I would interpret the #Beta here as a heads-up that "be aware, this API may change in future", but in practise the API is both stable, reliable and heavily used.
Maybe at some point, the google developers may choose to remove the #Beta annotation. Or maybe they intend to, or have forgotten (speculative...)
The "extra work" referred to means that, if you build an application using this API, you may need to refactor your application slightly (imagine that a method signiture changes, or a method becomes deprecated and replaced) if you need to upgrade to the newest version of this API.
The degree of work there depends on how heavily and how often you use the API, and how deep the dependency on that API is (transitively, through other libraries, for example - those would also need to be rebuilt).
In summary, in this case - "dont worry, move along" :)
So the implementation of the API is fine and stable?
No way to know from this annotation.
To answer that you need to know how widely used it is, and for how long.
Which kind of extra work?
The kind of extra work that you have to do when a method that required only 1 parameter and returned String now requires 3 parameters, and returns a List<String>.
i.e.: Code that uses this API might need to change due to API change.
So the implementation of the API is fine and stable?
The quoted text says that the API is "subject to incompatible changes". That means that it (the API) is not stable.
Note also that the quoted text explicitly states that the annotation is saying nothing about whether or not the API's implementation works.
But also note that this is not a yes / no issue. It is actually a yes / no / maybe issue. Some questions don't have answers.
Which kind of extra work?
Rewriting some of your code ... if the API changes.
The question is whether it is safe / stable to use mentioned class and its functionality?
This requires the ability to predict the future. It is unanswerable. (Unless you ask the people who put that annotation on that API. They may be able to make a reliable prediction ...)
It is also unanswerable because it depends on what you mean by safe, and what context you intend to use the Hashing class in.
What is the tradeoff while using a beta API?
The tradeoff is self evident:
On the plus side, you get to use new API functionality that may be beneficial to your application in the long run. (And if there is no evidence that it may be beneficial, this whole discussion is moot!)
On the minus side, you may have to rewrite some of your code if the authors modify the API ... as they say they might do.
In particular, the documentation for methods in PrefencesActivity shows many methods deprecated. However, the undeprecated methods are largely introduced in Honeycomb (API level 11). It would appear that if you are coding, as I am, in a pre-Honeycomb API, these methods are NOT deprecated.
So my question is, did I reverse engineer this correctly and is this a documentation bug? Should the deprecated comments actually say "deprecated as of API 11" or give some other indication that indeed these ARE the only choice methods if coding Gingerbread or earlier?
No, not exactly. Deprecated methods still function the way they normally did, it just means that they may not be supported in future releases and that you shouldn't use them in new code. That said, if you're targeting devices running older versions of the operating system, you have no choice but to use the deprecated methods.
import sun.net.www.protocol.jar.Handler causes the following warning:
sun.net.www.protocol.jar.Handler is
Sun proprietary API and may be removed
in a future release
There is no replacement. You have these options:
Use it and fix the problem if the API is ever removed (which won't happen in the next two years, at least). The most dangerous option but the most simple to implement.
Copy the code into a new class/package in your project to make sure it doesn't go away. Most safe, pretty easy to implement but you don't get bug fixes and classes in the runtime will still use the old handler.
Write your own extension of URLStreamHandler. Most work, least return of investment, high likelihood of bugs, most dangerous.
Rationale: This is a warning. Warning means: You may run into trouble if you do this. Use your common sense to decide.
Which is the best way you think to use Guava? Since, in the web site, the guys say that the interfaces are subject to change till they release 1.0. Taking this into account, the code you write shouldn't depend directly on those interfaces, so, are you wrapping all the Guava code you call into some kind of layer or facade in our projects in order to, if those interfaces change, then you at least have those changes centralized in one place?
Which is the best way to go? I am really interested in starting using it but I have that question hitting my mind hahah :)
I'm not sure where you're getting that about the interfaces being subject to change until version 1.0. That was true with Google Collections, Guava's predecessor, but that has had its 1.0 release and is now a part of Guava. Additionally, nothing that was part of Google Collections will be changed in a way that could break code.
Guava itself doesn't even use a release system with a concept of "1.0". It just does releases, labeled "r05", "r06" and so on. All APIs in Guava are effectively frozen unless they are marked with the #Beta annotation. If #Beta is on a class or interface, anything in that class is subject to change. If a class isn't annotated with it, but some methods in the class are, those specific methods are subject to change.
Note that even with the #Beta APIs, the functionality they provide will very likely not be removed completely... at most they'll probably just change how that functionality is provided. Additionally, I believe they're deprecating the original form of any #Beta API they change for 1 release before removing it completely, giving you time to see that it's changed and update to the new form of that API. #Beta also doesn't mean that a class or method isn't well-tested or suitable for production use.
Finally, this shouldn't be much of an issue if you're working on an application that uses Guava. It should be easy enough to update to a new version whenever, just making changes here and there if any #Beta APIs you were using changed. It's people writing libraries that use Guava who really need to avoid using #Beta APIs, as using one could create a situation where you're unable to switch to a newer version of Guava in your application OR use another library that uses a newer version because it would break code in the older library that depends on a changed/removed beta API.
I'm code reviewing a change one of my co-workers just did, and he added a bunch of calls to Date.toMonth(), Date.toYear() and other deprecated Date methods. All these methods were deprecated in JDK 1.1, but he insists that it's ok to use them because they haven't gone away yet (we're using JDK 1.5) and I'm saying they might go away any day now and he should use Calendar methods.
Has Sun/Oracle actually said when these things are going away, or does #deprecated just mean you lose style points?
Regarding the APIs, ... it is not specified they will be removed anytime soon.
Incompatibilities in J2SE 5.0 (since 1.4.2):
Source Compatibility
[...]
In general, the policy is as follows, except for any incompatibilities listed further below:
Deprecated APIs are interfaces that are supported only for backwards compatibility. The javac compiler generates a warning message whenever one of these is used, unless the -nowarn command-line option is used. It is recommended that programs be modified to eliminate the use of deprecated APIs, though there are no current plans to remove such APIs – with the exception of JVMDI and JVMPI – entirely from the system.
Even in its How and When To Deprecate APIs, nothing is being said about a policy regarding actually removing the deprected APIs...
Update 10 years later, the new JDK9+ Enhanced Deprecation clarifies the depreciation policy.
See Jens Bannmann's answer for more details.
This is also detailed in this blog post by Vojtěch Růžička, following criticisms on JEP 277.
The convention for JDK is that once a JDK API is marked as forRemoval=true in a certain Java version, it will be removed in the directly following major Java release.
That means - when something is marked as forRemoval=true in Java 9, it is supposed to be completely removed in Java 10.
Keep that in mind when using API marked for removal.
Note that this convention applies only to JDK itself and third-party libraries are free to choose any convention they see fit.
They're not going away. That said, they're usually deprecated because a) they're dangerous ala Thread.stop(), or b) there is a better or at least more accepted way to do it. Usually deprecated method javadoc will give you a hint as to the better way. In your case, Calendar is the recommended way to do this.
While it's conceivable that they will be removed at some point in the future, I wouldn't bet on it. If anyone ever forks Java however, they'll probably be the first thing to go...
One problem is you'll see lots of compiler warnings about using deprecated methods. If you also use deprecations to gradually phase out your own code, the compiler warnings will get lost in the noise and lose significance.
tl;dr
As of JDK 17, all original java.util.Date methods still exist, but these and other APIs can now be explicitly marked for removal. Many other deprecated APIs have been removed recently.
Full Answer
Before JDK 9, no deprecated API in the JDK was ever removed (see 20 Years Of Java Deprecation). That release, as part of a feature called Enhanced Deprecation, introduced the #Deprecated(forRemoval=true) flag and added it to dozens of previously deprecated APIs.
Also, for the first time in the language's history, JDK 9 removed APIs (full list from the Java SE 9 Specification) which had been deprecated by JDK 8 due to being an obstacle for modularization.
Since then, each JDK release has removed further APIs which were previously marked for removal, most releases have also added the forRemoval flag to previously deprecated APIs or added entirely new for-removal deprecations (see table below).
Key takeaways
Deprecated-for-removal APIs are very likely to be removed soon. Do take this seriously. While they may not be removed in the next release (e.g. Thread.stop() marked forRemoval in JDK 9, but was not removed before JDK 11), it can happen quickly.
No deprecated API is safe as even APIs that have long been deprecated could be removed quite quickly now: one JDK release sets the forRemoval flag, the following one removes the API. For example, the APIs that were removed by JDK 10 have been deprecated for at least 20 years (since JDK 1.2), so long that some people may now be surprised.
Nowadays, deprecations and removal happen much more quickly as Oracle switched to a 6-month release cycle with JDK 10.
Notable removals & proposals
Release
Removed
Deprecatedsince
Proposed for removal
JDK 10March 2018
Some APIs in the SecurityManager and Runtime classes(full list)
JDK 1.2
java.security.acl package, finalize() methods on certain I/O classes, several other previously deprecated APIs(full list)
JDK 11September 2018
Thread.destroy() and Thread.stop(), several other methods and the Policy class(full list)
JDK 9 & 10
java.util.jar.Pack200 APIs(full list)
JDK 12March 2019
finalize() methods of certain I/O classes (full list)
JDK 10
none
JDK 13September 2019
Runtime.traceInstructions() and Runtime.traceMethodCalls()(full list)
JDK 9
javax.security.cert package, methods on java.lang.String related to the "text blocks" preview feature and a few other methods(full list)
JDK 14March 2020
java.security.acl package and java.util.jar.Pack200 APIs(full list)
JDK 10 & 11
Thread.resume(), Thread.suspend() and related ThreadGroup methods; ConstantBootstraps(), Modifier() and ToolProvider() constructors(full list)
JDK 15September 2020
ConstantBootstraps() and Modifier() constructors(full list)
JDK 14
java.rmi.activation package(full list)
JDK 16March 2021
ToolProvider() constructor(full list)
JDK 14
Constructors of primitive wrapper classes such as Integer, Double or Boolean; ThreadGroup methods destroy(), stop(), isDaemon() and friends; URLDecoder() constructor; finalize() methods of certain color-related AWT classes(full list)
JDK 17September 2021
java.rmi.activation package, URLDecoder() constructor(full list)
JDK 15 & 16
java.applet package, java.lang.SecurityManager and related APIs such as checkAccess() on Thread/ThreadGroup(full list)
Well, "not gone yet" and "never going away" are two very different things. Thats the whole point of deprecation. They can go away with any future release. Using them is an at your own risk proposition. Just be aware that some future release of the JDK may leave your code in an unusable state.
I have a better recommendation: rather than telling him to use Calendar, you should switch to either JodaTime or JSR-310's pre-release version. Some methods on java.util.Date may be deprecated, but in my opinion the whole class should be deprecated, along with Calendar. The developers of JSR-310 seem to agree, although I doubt they'll ever bite the bullet and deprecate it.
In no particular order, here's what's wrong with Date:
Its internal representation is milliseconds since the epoch; therefore, cannot represent dates before the epoch.
All of its useful methods (e.g. toString) first normalize the date according to the local timezone. When working with UTC Date instances, this can get really annoying; you're forced to use Calendar or you will make very bad errors.
Calendar. It just stinks. Might win the award for worst API ever.
Always represents an instant-in-time. No way to represent specific days, or specific years. No way to represent timezone-less dates values.
Has almost no useful methods. See e.g. JodaTime's fluent interface for doing date arithmetic.
Should have been named Datetime, considering that it is one.
If the deprecated methods went away, they could break existing code.
While maintaining a clean API is important, the deprecated methods aren't getting in anyone's way. Sure, there are now better ways to do things, so new methods replace old ones. But there wouldn't be any gain made (besides a cleaner API) by getting rid of the old ones.
Think of "deprecated" as meaning "outdated", but not necessarily "on the chopping block".
Deprecated features features that are superseded and should be avoided. Although they remain in the JDK, they are discouraged as there are better methods available. The methods are left in the API to support backward compatibility, but should generally be avoided as they could be removed in future versions of the API.
It is technically ok to use deprecated methods, but generally the reason it was deprecated in the first place was that a better/faster/cleaner API has been developed.
Sun tend to be extremely paranoid when it comes to changes that impact backwards compatibility, so I wouldn't expect to see the methods go away any time soon.
But deprecated methods could go away at any time in the future, and are normally deprecated for a reason - either because they're unreliable, because they have unpleasant side effects, or simply because there's a better or more elegant way of doing things. The JavaDoc for the method will normally detail which of these is the case and what the acceptable way of carrying out the same operation is these days. Quite frequently the deprecated method will have been replaced with an implementation that calls the 'correct' method anyway, so you're just adding a level of indirection anyway.
You'll also have plenty of compilation warnings if you use these methods, which could be reason enough to avoid them in itself...
I've definitely seen deprecated functions go away - from old versions of Java to the current (I started on 1.1, and some stuff distinctly DID NOT WORK in 1.4).
Other languages handle deprecation differently - Python has been known in the past, for example, to remove deprecated functionality after just a release or two.