Puh-leeze, get rid of that *$@%!&* final keyword in Java! It's making my life bloody difficult at the moment. Thank you.
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...
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.
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.
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 ;-)







