One does not simply 'stop calling' Java's deprecated methods

They’re deprecating finalize.

That’s a pretty drastic move. Finalize is defined right there in the Object class, right at the top of the Java hierarchy, more exposed than a public variable. But the semantics of the finalize method are tied to the JVM’s infamous garbage collector. Nobody designing the API twenty years ago would have imagined that twenty years after declaring the finalize method, the garbage collector would still be thoroughly unpredictable in its trash collection patterns; if they did, they never would have coded it in the first place.

The finalize method must die, because banking on the JVM’s gc system, and subsequently tying functionality to the death of a POJO, is bytecode-based malevolence. So in a near future release, there will be a little @deprecated annotation placed on the finalized method. So what exactly does that mean? In the Java world, it means very little.

One does not simply stop calling deprecated Java methods

One does not simply stop calling deprecated Java methods

Hiding Java method deprecation problems

There are plenty of deprecated methods in Java, and there’s nothing stopping you from calling them. Sure, a yellow yield sign might appear in the line-number bar of your Eclipse or NetBeans IDE, warning you that you’re calling one of Java’s deprecated methods, but that’s about it. An easy way to address this issue is to go into the IDE’s preferences window and tell it not to report calls to deprecated methods. Just perform that quick change, and maybe do a rebuild, and all of the deprecated method warnings will go away.

Another approach is to decorate the the code you write with the @SuppressWarnings( “deprecation” ) annotation. That’s another simple way to make your deprecation problems disappear.

Java method deprecation problems solved

For those managing the Jenkins build, at the compiler level, you can use the -Xlint:all switch on the compiler to stop you from the seeing warnings about deprecated method calls during your Gradle or Maven builds. Really, there are a variety of approaches to dealing with deprecated methods; these are just some of the more common ones.

Of course, some might argue that the proper approach is to just stop calling deprecated methods. There may have been some impetus to do that ten or fifteen years ago, when a deprecation warning made a developer feel like a clock was ticking, and when the timer ran out, their code wasn’t going to work anymore. That would be true if deprecated methods were ever pruned out of the Java SE suite of APIs, but they never are.

I still see users calling the deprecated java.util.Date() constructor. The last project I was on was replete with calls to the deprecated URLEncoder.encode(). Sure, people shouldn’t be calling Java’s deprecated methods, but given the fact that they work, compounded with the fact that fifteen to twenty years after being deprecated they’re still hanging around as part of the API, developers just keep using them. Simply telling developers to ‘get with the program’ clearly isn’t good enough.

Java method deprecation and backwards compatibility

So why do they keep leaving all of these deprecated methods in the spec? I was once told that pruning usually happens on a full increment release, and since Java has never transitioned to version 2.0, there’s never been a need to.  (Although Java boasts version 7 and version 8 releases, the actual version increment is 1.7 and 1.8.) There’s also something to be said for backwards compatibility. Not removing deprecated methods from the spec makes old code forward compatible with future compilers, and that certainly makes maintaining old code easier.

But the Java approach to never pruning deprecated methods out of the spec is not a universal one. In contrast, Spring has always been aggressive in taking unloved functions out of the codebase. “It seems that the view of Java is that deprecation means nothing, whereas our view of deprecation is that if you deprecate something, you take it out in the next major release,” said Rod Johnson a number of years ago when discussing the Spring framework and it’s dedication to backwards compatibility.”Deprecation actually says something. It says ‘this is going to disappear in probably 18-month’s-time.’”

The fact is, whether it’s the JVM’s gc process to blame or not, the finalize method  never did what it was supposed to do in the way that people expected. That in itself is reason enough to vote it off the island, so the @deprecated flag is certainly warranted. But don’t just deprecate it. Grab the hedge clippers and put together a plan to cut it out and throw it in the garbage. Of course, that really is the problem, isn’t it? Java has never had predicable garbage collection services.

You can follow Cameron McKenzie on Twitter: @cameronmckenzie

App Architecture
Software Quality
Cloud Computing