login
Blurts on the Art of Software Development

Today | RSS | RDF | Atom | Other Tags
Categories : All | All | CI | .NET | General | Humour | Java | Personal | Reviews | Ruby | SW Eng

Puh-leeze, get rid of that *$@%!&* final keyword in Java! It's making my life bloody difficult at the moment. Thank you.


How so?
Why not elaborate a bit?
I think I heard of a tool that alters .class files to remove "final" declarations embedded therein. If you find such a tool, let us know if it works.
What is there so problematic with the "final" keyword exactly? Can't remember having much problems with it.

The outburst was because I would've wanted to write a test for a piece of code that works on classes from the java.lang.reflect package such as Method and Field. Well, those are final classes which means that 1) you can't extend them to fake out a method, and 2) you can't point EasyMock at them to fake out a method.

That, plus the small thing that I don't consider the final keyword being useful in the first place. It's purpose is to prevent a developer from extending a class that's not meant to be extended. Alright, I get that. Except that it would be sufficient in pretty much any circumstances to loosen up that strict requirement and use documentation instead.

The developer who's prevented from extending a class he probably already knows should not be extended. Oh, and he can't write a test to protect the codebase from regression.

That's about it. And it's just me. I'm fully aware that others opinions may vary from mine with regards to this. It's just that I'd prefer testability over rigidity...

Ok, now I understand your pain. One pain in the ass also is trying to mock java.io package classes, like java.io.File, which is marked as final. What a great idea! One way to survive is to use the alt.java.io package from <a href"http://www.mockobjects.com/FrontPage.html">mockobjects in your code, or implement your own file handling wrappers. I usually solve this by not using the File class at all in my own code, but take Streams as parameters instead. Then at least I have some classes that can be elegantly tested. :-)
I think final classes have a valid place in guaranteeing immutability. I ran into a problem where I needed to test a class that another developer wrote which was final and had no interfaces. I solved the problem by walking across the hall and asking him to expose it as an interface. Thus my epic battle with final was concluded.
Removing final would be a terrible idea, even if you only remove it from class definitions. The use of final in member and variable definitions is how you implement immutability, and that allows all sorts of optimisations in the hotspot compiler.

For more info see: Java theory and practice: Is that your final answer? or Java theory and practice: Garbage collection and performance

Also, have you looked at whether AOP may be able to instrument the classes you want to test?

True, there are benefits to the final keyword. It just seems like that it's mostly used in places where it's not really giving any real advantage over a more flexible way to accomplish the same goal of "do not touch this unless you really know what you're doing". For the most part, as far as I can see, it's not used for performance reasons. It would be interesting to see some micro benchmarks about the effect of adding the final keyword to selected places on an immutable class.

Why is java.lang.reflect.Method, for example, final? Why not provide an interface and make the implementation final? I wish I could walk down the hall. Instead, I considered it was easier to just rant in a blog.

Jed, no, I haven't tried an AOP solution yet. I don't think I'm going to introduce something like AspectJ to the project just to be able to test the small slice of reflection stuff that was causing trouble. I'll make a note of testing whether another, all-Java AOP framework like Aspectwerkz could handle it.

By the way, regarding "use of final in member and variable definitions is how you implement immutability", I beg to differ.

That's how you enforce immutability. There are other ways of implementing immutability. This is not too different a relationship as that between the Singleton pattern and JustCreateOne.

Well, if you don't enforce immutability, you don't get any of the benefits - specifically, the JIT compiler cannot copy references on to the stack, so you don't get quite a few of the performance improvements. BTW. AspectWerks and AspectJ joined forces and the latest AspectJ 5 now supports a completely annotation based style and doesn't require the aj compiler anymore.

I consider the main benefit of immutability being the (potentially) gained simplicity in design. I don't remember personally hearing/seeing anyone make objects immutable because of the performance boost they might yield.

I did take a quick look at AspectWerkz 2.0, by the way, and it would seem to be more effort than it would be worth just to be able to test what I wanted to test.

There are two significant performance benefits of final fields. Firstly, generational garbage collectors much prefer new generation objects that contain references to older objects. Immutable objects will almost always contain references to existing objects when created, or at the very least they contain references that are of the same generation.

The second is that under the revised memory model in JSR 133, aggressive optimisations are possible in multi-threaded contexts, specifically that the references may be copied to the local thread stack without any synchronisation, and never need to be reloaded. Many modern JIT compilers already implement these optimisations, and more are coming in Mustang.

Of course, in a Java EE context, as soon as you do a remote call, query a DB or the like, the performance improvements we are talking about are negligible to the cost of those calls anyway ;-)

I've always been hazy in this area, but wouldn't removing 'final' open up some security holes, also? If any class can be extended/overridden, I would think it would make some of the core runtime classes vulnerable to malicious tinkering.


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 1 + 7 = (Helps stop blog spam)
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

TrackBack to http://radio.javaranch.com/lasse/addTrackBack.action?entry=1136299429306