A post by Bill Venners, comparing the way Python and Java handle deprecation, caught my attention while surfing java.net . While Java prefers the Warn-and-forget way, Python takes the other extreme of removing old features altogether. Bill discusses the pros and cons of each method i.e – lean and clean libraries vs. backward compatibility.
Personally, I would prefer Java followed the Python way; allowing older features to co-exist through minor revisions ( like 2.x versions) and remove them with the next major revision (like 3.0). IMO deciding to take the leap (migrate) to next major version of a library, framework or platform is a non-trivial decision, considering the large number of feature changes involved. And that's what major revisions are for!
To clarify further, let's say I migrate my Java app from JDK 1.4 to JDK 5.0. For e.g. If I am still using the Collections, old style, without generics, don't utilize new for-loop and auto-boxing/unboxing to make the code less cluttered, what benefit do I reap by using latest and the greatest version? I would be better of sticking with 1.4 version for some more time (as long as it's supported)
Most migrations to next major version happen, NOT because the project wishes to use the new enhancements, but to remain saddled with the latest supported version. Given this reason, if Sun were to totally remove all deprecated methods from since the last major version, projects would still migrate. And in the process enjoy the benefits of using newer/advanced features.
But, that's the last thing SUN is likely to do. It would takes months for 1.4 projects to use 5.0 (which they ultimately will!), meaning longer support period for 1.4 and a more protracted adoption period for 5.0. It would be more easier to mark stuff 'deprecated' and move on, achieving 80% adoption within months.
It's not that SUN has a pristine record for backward-compatibility. Just try running EJB 1.0 apps in latest servers. EJB 3.0 deprecates most of EJB 2.0 way of doing things ( Entity-Beans no longer exist!). When SUN can come up with such massive deprecations at an Enterprise level, how come SUN's so fanatic about retaining deprecated JDK functionality?
First of all, the flawed versioning system. While Java was at version 2.0 (Java2) JDK version was kept pegged to 1.2. And now that Java is at version 5.0, JDK uses an internal versioning of 1.5. I can understand Java 2 situation, adding static/inner classes [of various flavors] might be forgiven for not bumping up the JDK version.But, if adding features like generics, enums, new for-loop etc. don't appear to warrant a major JDK version changes [in their thinking], I don't know what-else will?.
Secondly, the complacency caused by the @deprecated JavaDoc tag. It's cheap to use. I've seen used for trivial name changes [ l-o-o-o-nger names], addition of newer better methods, addition of parameters etc. While it's extensively used, it seldom serves it's purpose. More often than not, compiler warnings tend to be ignored; given the project deadlines and budgets. Deprecated methods keep building over time and soon it becomes near impossible to remove them as there could be countless projects using them ignoring the warnings. If SUN were to remove all the deprecated methods in the next version of JDK, it would be months (if not a year) before that version gains acceptance as mainstream.
IMO @deprecated is a half-baked measure that could have been used better. There is no standard way to capture when the deprecation happend (which version?), upto to what version the method will be kept, and when shall it be removed. For e.g it could've been -
@deprecated since(1.1) allow_upto(1.3) removal_plan(1.5)
For versions prior to 1.3, say 1.2, the compiler could issue a warning ' Deprecated since 1.2. Will be removed in 1.5'. For version 1.4 compiler should stop with the compilation error 'Deprecated method disallowed after version 1.3. Scheduled for removal in version 1.5'. This will cause a slight heart-burn, but it will also ensure that dyed-in-the-wool slobs stop using those features. On reaching 1.5 the feature can be safely removed.
Wouldn't it make the life easier for all of us?
@depecated Deprecated by @Deprecated
@deprecated tag itself has been deprecated by @Deprecated annotation since Java 5. Now you need to give @Deprecated annotation to inform the compiler of code deprecation, and @deprecated JavaDoc tag to add reaons of deprecation to JavaDocs. How ironic, that the venerable feature itself should become an example of 'Deprecation' and the redundancy/code-bloat it causes.