Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Saturday, September 4, 2010

Why I don't like Java's finals

Although I favor immutability over mutability, I must say that I don't like Java's finals. The intention when introducing it was definitely great and good, but I think it does more harm than provides benefits.

Consider the following.

Finals prevent you from mocking classes.
Yes, they do. I hardly know any framework that is capable of mocking class that is final; you can play with some workarounds like unfinalizers or framework extensions to do the trick, but it comes for the price of a test / test set-up complication (at least) and an additional cost (running time, introduction time).

There are people who suggest that you don't need to mock classes for your tests, but I hardly find it acceptable: imagine yourself writing unit tests for class that uses a "final" server as a parameter:

class LogCollector {
   public LogCollector(LogServer server) {
     // whatever
   } 
}


I personally prefer to use fine-grained tests before running large test routines (requiring real server instance set up, for example), but given the server is final, I have no choice - I am left with large tests, with all their costs.

Finals lie to you.
Consider the following code:

final Set customers;

It's true, that once assigned, the customers set cannot be assigned once again, but you can still modify the set anyway - it's a matter of calling customers.add(Customer). Unless you're using an UnmodifiableSet, nothing prevents you from changing it's contents.

Finals force you to predict future.
I'm not much of a subclassing fan, but it is understandable to subclass something from time to time to enhance a bit the functionality already given. With finals, you can't do that by design. Thus, you have to predict the possible future use of your objects - and I feel no one was able to do that for something more complicated than a primitive type.

Disabling subclassing may also be a pain in an inflexible type system like Java's:

class NoisyCar {
   void run() {
     System.out.printl("BRRRRRRUUUUUUM");
   }

   // other methods 
}



class QuietCar {
   void run() {
     System.out.printl("brrrrrruuuuuuum");
   }

   // other methods, same as in Car 
}

X rentedCar = carRentan.getAvailableCar(); // We don't know what do they have available, but we need a car immediately

What's the type X?

Possible solution 0: Ducktyping. Not in Java.

Possible solution 1: We could use an interface Car, but then we get some serious code duplication (we would have to either copy-paste other methods or refactor out common code to a separate class, which may - in this case - seriously complicate your life).

Workaround: If we had functions as first-class values, we could probably come up with not a bad workaround and carry on with finals, but... well, we don't have them in Java.

Possible solution 2: Allow removing final, introduce a superclass and let NoisyCar and QuietCar subclass it.

Any other ideas?

Finals prevent you from flexible debugging.
I've found out that recently: while debugging, you cannot change the value of the final variable (it's not a surprise, though). What's the problem? You cannot experiment - while debugging, you cannot change the value of an interesting variable and thus you're sticked to a certain path of execution. Bad, if you encounter it in real life.

Finals encourage bad practices.
Namely, they encourage you to expose fields of a class. Since no one can change them, what's the big deal? Well, there is. You're explicitly saying the class users: this field is publicly available. You can use it. Once you change your mind and, for example, decide to provide an active getter (fetching missing data, for example) with some decoration around it (like sanity checks) you can't - someone uses the field already. And you cannot deprecate a field to let users know it's going to be gone, can you?

On one hand, it's bad to create not-fully-initialized objects. On the other, lazy evaluation may be a great optimization. It's all up to the case you're dealing with. Will finals help you? Well, they limit your flexibility and let the implementation leak, so you may have trouble.


That's my 2 cents. Please read both why finals should be deprecated and why they shouldn't and make up your mind. In my personal opinion, they rarely are worth using.

Edit: there is some follow up on this post here.

Thursday, April 8, 2010

Java object serialization - 5 things you should know about

This is an article that a Java developer should be awared of. It's not really innovative; it just points out the basics that one should know when it comes to serializing an object in Java. For more exhaustive lecture (covering many more important issues related to Java programming), I suggest reading Effective Java by Joshua Bloch.

By the way, if you didn't read Java Generics and Collections by Maurice Naftalin and Philip Wadler (homepage), you really should.

Saturday, January 2, 2010

Kilka oczywistych rzeczy o kreacji obiektów w Javie.

Mało zaskakujące.

Mutability, Arrays and the Cost of Temporary Objects in Java

No, może poza tym, że wołanie "values()" na typie wyliczeniowym w Javie nie jest najrozsądniejszym wyjściem. Wygląda na to, że ze względu na nietrwałość/ulotność (lepiej brzmi niż niemutowalność, czyż nie?) zastosowano tzw. defensive copying - choć to już mało istotne.

Modyfikacja kodu w locie

That sounds interesting.

JMangler is a framework for generic interception and transformation of Java programs at load-time.

 Nie żeby to była jakaś nowość, ale możliwości tego narzędzia wydają się być naprawdę spore.

Saturday, December 12, 2009

Java EE 6 opublikowana

Jako programista Java muszę wspomnieć o takim wydarzeniu. Cała praca związana z przedstawieniem nowej platformy została już wykonana - pozwolę więc sobie tylko do niej przekierować:

Java EE 6 feature overview

Miłego czytania :-)