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

Sunday, July 31, 2011

The power of immutability

The final keyword in java has a wide scope of usage. It can be used with:

  • classes - public final class Foo {...}
  • methods - public final void Bar() {...}
  • member variables - private final int a;
  • local variables - final int xMin = 2;
In generally the final keyword makes the corresponding class/method/variable immutable.  
For classes and methods immutability means that it can not be specialized respectively overridden, whereas for variables it means that after the initialization, their value can not be changed.

Java does not make any analysis of your classes, so member variables declares as final must be initialized in the constructor of the corresponding class. After the initialization, their value is freeze.


Consider the following snippet:

1:  public class Foo {  
2:    protected final int xMin;  
3:    protected final int xMax = 10;  
4:    
5:    public Foo() {  
6:      xMin = 5;  
7:      xMax = 10; // This is of course a compiler error  
8:    }  
9:  }  
10:    
11:  public class Bar extends Foo {  
12:    public Bar() {  
13:      super():  
14:      xMax = 15; // Compiler error  
15:    }  
16:  }  


I used to use final really intensive in my code, for two reason:
  • it reduces the possible states of a class
  • it makes multithreading a lot easier
The possible states of a class are reduced, since the amount of its members that might change (put the class in a different state) is reduced. It makes much more easier to understand, but also to test your classes. Further more, it reduces the possibility of failures. I saw an extreme example, how bad it can come. 

If you use final, it is good to know how it really works. Consider the following snippet:
1:  public class Foo {  
2:    private final List<String> names = new ArrayList<String>();  
3:    public void addName(String name) {  
4:      names.add(name); // this gonna work 
5:    }  
6:    public void releaseList() {  
7:      names = null; // compiler error  
8:    }  
9:  }  

For some time ago I received an issue that I had to fix in some module, that I was not familiar with. I tracked down the bug to a particular class, and I recognized that the class has more than 20 member variables and about 15-20 methods on them. In this particular case it is not just an issue of immutability, but also of a poor or even missing design. After some basic refactoring (only aiming to reduce the possible states of the class) about 16 of the member variables was transformed in a final variable. This step made the class much more easier to understand and to manage. 

If you go further it is even meaningful to use immutable variables in a method. These provides some hints on your intentions, and might help in the future if you need change the method or fix bugs.

Now, let's consider the impacts of immutability on multithreading:

One of the most difficult things about writing concurrent programs is deciding how to protect mutable shared state. Java provides a locking primitive, synchronized, but locking primitives are difficult to use. You have to worry about


  • data corruption (if you lock too little)
  • deadlock (if you lock too much)
  • performance degradation (even if you get it right)
Using immutable objects, you don't need to take care about synchronization. Functional languages, such as SCALA do enforce immutability, and are really powerful in multithreaded applications.

Tuesday, July 26, 2011

My thoughts on assertions in Java

An assertion is a statement in the JavaTM programming language that enables you to test your assumptions about your program. For example, if you write a method that calculates the speed of a particle, you might assert that the calculated speed is less than the speed of light. 


Oracle gives clear statements where assertions should be used, and in which situation you should avoid using them, however, I used to use assertions in a bit different way.

Assertion is not just a good stuff to check invariants, pre- and postconditions in your code, but it helps for your colleagues by working with your code. You can understand assertions as a kind of security cordon.

They tell a lot for someone who need to fix some bugs or implement some additional feature in or to your code. In many cases they are even more useful than comments (ok, I'm clearly not a fan of comments... just se my corresponding post).

Oracle says: Do not use assertions for argument checking in public methods.
You should follow this for your public API. You really should. But I decided to use assertions in my library internal classes for public methods too. In my team we use assertions in a pretty intensive manner, even in public methods, and for arguments checking, and the helped us a lot. I prefer them over exceptions. You can read in an old post of Joel Spolsky about exceptions:

"... In fact they are significantly worse than goto's:
They are invisible in the source code.
They create too many possible exit points for a function.
..."


Consider the following code snippet:
public class CommandExecutor<T extends Target> {
    private final T targetOfExecution;
    
    public CommandExecutor(T targetOfExecution) {
        assert targetOfExecution != null;

        this.targetOfExecution = targetOfExecution;
        ...
    }

   ...

    public void execute(Command<T> c) {
        // prepare target for command execution
        // do not need to check the targetOfExecution

       // I prefer to get some assertion during development and tests
       // instead of waiting for a runtime np-ex
       assert c != null;

      c.execute( targetOfExecution );

     // do some post operations
    }

}

Assuming that this class is internal to your library, and not part of the private API, the assertion in the constructor will do a favor for you.

Instead of exceptions the assertions can be turned off, so you can combine them with return values to improve the quality of your source.

Further more combining assertion with immutability, the execute method will be more readable, since you can save some null checks.

I would be happy to read your thought on this topic.

Saturday, July 16, 2011

Comments on code comments

Some easy topic for saturday evening!

Please do not comment your code!
Or do it less than you do now!

I know you have learned that comments are good, and yes, I was very happy to see lots of comments in an assembly code, but please, do not comment each line of your java code.

Consider the following snippet:

1  /**
2   * This method calculates some value.
3   * @param stockId stock identifier
4   * @return integer value
5   */
6   private int calculateSomeStockValue(int stockId) {
7       // the initial value of the algorithm
8       final int initialValue = 10;
9
10      EntityManager em = null;
11      try {
12          // create an entity manager to access the database
13          em = this.managerFactory.createEntityManager();
14          assert em != null;
15
16          // read the stock from the database
17          final Stock stock = em.readStockValue(stockId);
18
19          // if no stock found return the initial value
20          if ( stock == null )
21                return initialValue;
22
23         // retrieve the average price of the stock
24        final double stockPrice = stock.getCurrentPrice();
25
26         return stockPrice;
27      } finally {
28             // close the entity manager if not null
29             if ( em != null )
30                 em.close();
31      }
32 }


Just be honest, what additional information gives you those comments? I mean in spite of the fact that they make the code unreadable, and they are probably even false (see line 23,24 - is it a bug in the source, or just an old comment)!


Do not comment your code, or if you comment it consider writing useful information! Rather then use speaking variable and method names. Don't be afraid of long names. Your code will more readable through them.


Less comment is more!