zondag 11 september 2016

The six benefits of final

Ever since I returned to back to "the Duke side of the Force" I  am pleased when I can type a specific word of 5 letters: final.  Final means you cannot change it after it was set or defined.  In functional programming languages final is the default and usually implicit. At the cost of five characters more verbosity per declaration you get the  same six benefits functional languages give you for free. With final code is easier to:

  1. understand.
  2. maintain.
  3. document.
  4. debug.
  5. make parallel.
  6. optimize for a compiler.

In the rest of this post I will explore possible uses of the word final in Java.

Final for constants

Java has no keyword for constants but uses final. A constant in Java is defined within a class like:

public static final int ULTIMATE_ANSWER = 42; 

Constants are written in SNAKE_CASE in Java. Really something to get used to if you come from some other environment.  And yes const  like in C#, or JavaScript is more succinct. If you want to constrain the use more you can use package visibility, protected of private if you like.

In more recent versions of Java enums can be used for the same purpose if you use int values.

Final for fields

You can use final for fields. This enforces setting them in a constructor. Something like

public class DutchAddress{
  private final String street;
  private final int number;
  private final String postalCode;
  private final String city;
  public DutchAddress(String streetValue, //
    int numberValue, //
    String postalCodeValue, //
    String cityValue){
    //include some argument checking.
    this.street = streetValue;
    this.number = numberValue;
    this.postalCode = postalCodeValue;
    this.city = cityValue; 
  }
 //.. only add getters!
}

If I do not add a constructor or only a default constructor I get a compile error.
Using the constructor as above I am sure DutchAddress never contains uninitialized values for its fields. 

Taking care of argument sanity is something for another blog post.
 However making this constructor private and provide a factory is a possible solution if you do not want to throw exceptions in a constructor.

For the remainder of this post we assume we do not use final for the fields.

Final in method signatures

It is sometimes common practice to do argument checking on the arguments of a function and change the arguments value in the process. Something like the following.

public class DutchAddress{
  private String street = "";

  public void setStreet(String value){
    if(value == null){
      value = "";
    }
    value = value.trim();
    this.street = value;
  }
  //...
}

Now imagine you are debugging the code above somewhere in the middle, or actually a bit more complicated code that does something similar. You cannot lookup the original value of value easily.

At the cost of using final and introducing an extra variable you can be sure the original value can be seen when debugging.  I change the code as follows:

public class DutchAddress{
  private String street = "";

  public void setStreet(final String value){
    String checkedValue = value;
    if(checkedValue == null){
      checkedValue  = "";
    }
    checkedValue =checkedValue .trim();
    this.street = checkedValue ;
  }
  //...
}


Yes, I know:

  • This argument only holds for non mutable types. But a lot of my coding involves ints and Strings as arguments.
  •  I use value here as name of the argument instead of street. I think it is more DRY.
Using final is a promise to the compiler, yourself, your later self and the guy after you, that you do not play tricks with the arguments.

For a setter this is a bit verbose. I can improve on that and also lose the explicit temporary variable.



public class DutchAddress{
  private String street = "";

  public void setStreet(final String value){
    this.street = (value == null?"":value).trim();
  }
  //...
}

Final in the body of a method

Final in the body of a method works a bit like a const but it can change on every invocation influenced by the arguments or the state of the object.

public class DutchAddresses{
  private final List<DutchAddress> addresses= //
    new ArrayList<DutchAddress>;

  public void addVerifiedAddress(final String street, //
     final  intnumber, //
     final String postalCode, //
     final String city){
  //we assume the arguments are fine for now ;)
  final DutchAddress address=new Address(street,number,postalCode,city);
  //...
  
  // do some amazing verifications here
  
  //...

  //we are certain the same address object we created earlier is added.
  //Since DutchAddress is mutable it's fields may have changed.
  addresses.add(address);

}

Here I am sure that the reference to address never changes within the current call of the method once it is set.

Final in for loops

Java has a special kind of for loop that is known as an foreach loop in other languages.

It has the following form:
for (DutchAddress address :addresses){
 //do something with the address
}

Unfortunately the reference to address is modifiable like with the method arguments without final keyword. You can do this.

for (DutchAddress address :addresses){
 //do something with the address
 address = new Address("Noordeinde",68,"2514GL","Den Haag");
 //do some more with the overwritten address
}

The guy living at the newly instantiated address is lucky for multiple reasons! One reason is that he never ends up in our address list.  To prevent such error superhero final rescues us.

for (final DutchAddress address :addresses){
 //do something with the address
 address = new Address("Noordeinde",68,"2514GL","Den Haag"); // compile error
 //do some more with the overwritten address
}

Every iteration an address is retrieved from the list of adresses which cannot be changed in the body of the loop. However since an instance of DutchAddress is mutable its fields can be changed.

Final at the class level

public final class DutchAddress{
 //..
}

This means you never intended the class to be extended. It is a clear message to your later self and the guy after you in the role of maintainer. It also allows a compiler to do some optimizing.

Making a class extensible, aka non final places great responsibility on the base class designer. The guy extending your code may not have access to the source. So you must make it bullet proof and document the extension points very well. If someone is using extended code and it breaks in the base class who is to blame?


Final at the method level

Final at the method level is similar to final at the class level. It forbids overriding a method.
Since I usually make classes final I haven't used it in Java or the similar 'sealed' construct in C#. A crazy thing you can do to test your IDE with final is making an abstract method final. At least Eclipse gives the wrong advice about making the method public or protected. 

public class DutchAddress{
 //..
 final boolean isValid(){
    //...
  }
}


Final in try with resources clause

Since Java 7 try /catch is extended with the option to declare resources that get released when they get out of scope. This is similar to a .NET using clause  but with the added benefit of being able to catch Exceptions. However in Java the references to the resources are mutable where they are 'final' in .NET. However you can make them immutable by declaring the resources final. Resources must implement the interface java.lang.AutoCloseable

Example:

try( final MyAutoCloseableResource reader=new MyAutoCloseableResource()){
 //... do something
}catch(Exeption ex){
//... log something and do some exception handling
}
//.. here is an implicit finally clause closes the autocloseable if it is not null.

The added final makes sure we dot leak resources in the body of the try.

Disadvantages of final

There are some disadvantages on final. First of all, it is not DRY because final is not the default in Java. You have to use it again and again to enforce it. Code checking tools like findbugs or Sonarqube may help to discover violations and or enforce it.

Second method signatures may become very long with multiple arguments. 
It becomes worse if you also add argument validating decorators which will be the topic of another post.  e.g. a method signature like

public void addAddress(@NonNull final String streetValue, //
  @IntRange(from=1,to=9999) final int number, //
  @NonNull String postalCodeValue, //
  @NonNull String city){
//..
}

Third, a trick to test classes is to subclass them and override methods. Sorry you better use a proxy for that.

 Finally, making fields final in existing code is usually undoable without major API redesign.

Recommendations

I recommend making:
  • classes final that you never intend to extend.
  • loop variables in a 'foreach' style for loop final.
  • arguments of methods final.
  • declared variables in methods final as much as possible.
I think making fields final is hard. It goes against the Java Beans Idea and requires additional methods to make it usable by other programmers. In existing code it is not doable but perhaps your team can agree upon doing it on new code.

Finally

'Finally' is another nice keyword out of the scope for this blog post.
Yes I know about using specific types for street and postal code but that is out of scope too.
If you are interested in that, read Scott Wlaschin's excellent series on Desiging with types.
Also available as video conference talk via his website. Enforcing that style in an existing codebase may be an "interesting" exercise. In a next post I try doing that a bit using decorators.
  • What's your favorite keyword or language feature and why?
  • What is a valid use for final at the method level?
  • What is the maximum number of arguments you allow in a method?
  • What is the maximum number of characters you allow in a line of code?
  • Tabs or spaces?


What's Next

  • Decorators to constrain types.
  • Streams.
  • Automatic Getter/Setter and more testing for Beans.


What's wrong with Java Beans?

TLDR: This is my rant against the concept of Java Beans.
Im my previous post I mentioned that beans are a great way to compose a solution out of smaller parts. I also mentioned writing generators for the boilerplate of a bean. Such generators are now standard in modern IDEs.  Sadly one important thing Java does not have is real properties. Syntactic sugar for properties is present in  languages like: C#,  F#, Scala, Kotlin and Ceylon.


Programming is a way of communicating your ideas:
  1. To yourself
  2. To your later self
  3. To your coworkers
  4. To the unknown people that have to maintain your crap(often politely called legacy).
  5. To outside programmers, aka customers, if you are writing a library.
In daily life we use  words, sentences paragraphs etc to express our ideas. For a frequently used idea we use  single word as  succint way of communication, a shared understanding.

Java Beans are a little bit more verbose. They use sentences to express  simple ideas:
  • For just a simple object holding a Person's details you have to add fields, getters with comments and setters with comments. 
  • Supporting one field requires at least 15 lines of code.
  • These lines need tests too! 
  • This code needs to be maintained by you, your future self, coworkers, and the guy after you.  Customers have to read about the getters and the setters from the Javadocs.
  • These lines clutter your codebase.
When Microsoft copied  improved upon Java by inventing C# they did at least one thing right. They introduced syntactic sugar for properties. Nowadays a simple property in C# is just one line, almost like a public field.  Example:

public string Name{get; set;}="John Doe";

That is:
  • 14 lines less to be read. No clutter!
  • One line to be maintained by you.
  • One line to be maintained by your future self.
  • One line to be maintained by coworkers.
  • One line to be maintained by the guy after you.
  • Much less documentation to be written.
  • Less tests to write.
  • More time to break other stuff.
Languages such as F#, Scala, Kotlin and Ceylon even improved this further. A simple class definition in these languages is a one liner:

class Person(string name, string address);

Often forgotten methods

Write default constructor, the getters, setters, the related tests and the Javadoc and your beautiful bean  is ready for use? Wrong!. When your bean is used in  collections the collection framework uses equals(...) and hashCode() for sorting bean instances. If you do nothing the equals() and hashCode()  of the super class  Object  will be used. This is usually not what you want.

For debugging purposes having a custom toString() function is a nice to have,
If you add these you already  have some code to maintain and write tests for.

Unlike C#, Java does not allow operator overloading so there are no operators to overload.

 F#,  probably other languages too, even goes a bit further by also including sensible implementations for comperator functions. These functions are more important if you use Streams. To the .NET programmer: Streams are Java's way to LINQ without syntactic sugar in the language.

Ease the pain with code generation

IDEs like Eclipse come with  code generation functionality. You can:
  • generate getters and setters form fields.
  • generate a  hashCode() and equals(...) function.
  • generate a toString() function.
 In a language like F# these functions are generated by the compiler automatically. developers do not see these functions so nothing to maintain or break.

Sadly there is no support for maintainance. Maintainance when adding, changing or deleting fields to a bean, are left to the crafmanship of the developer. This will not change in coming Java version 9.  We have to live with it for near future.

 I wonder, how do you count your beans and check whether they are in good shape?

What's Next

  • A final word or a word on final.
  • Decorators to constrain types.
  • Streams.
  • Automatic Getter/Setter and more testing for Beans.

dinsdag 6 september 2016

My Java Life

 This first blogpost on this now new blog, is a trip to memory lane about  my first encounters with the Java programming language. I spent the last ten years developing in .NET but before that did use Java. At the end of 2015 I got a Job offer I could not refuse but... It included Java EE and Android development.  Ok.. while teaching others about .NET LINQ, lambda's Monads, OData and JavaScript I started  relearning myself Java, Java EE and Android. I also peeked into Scala, Akka, Play, Kotlin and Ceylon again.

First encounters

I was introduced to Java in early 1995 at the ACM European programming contest. We lost but there were great talks by Sun and Andrew Tanenbaum. I still have some Duke pins somewhere. During an internship and my master thesis I used Java. For .NET heads. Duke, a funny figure with a red nose is Java's Mascotte since at least 1995.

Second encounter

To get up to speed with Java again, I read some books on what has Changed in Java 7 & 8 first and then focused on learning Java EE and Android development.  A lot has changed since 2005. IDEs have improved a lot. J2EE got rebranded Java EE. Why didn't anybody tell me that??? Search books for J2EE gets you ancient stuff. If you search for Java EE you get less ancient stuff.  I carefully consulted coworkers and the online Java community whether I was learning the right stuff. I teached  C# 3.5 once. Some of my students came to me with ancient 1.0 solutions. That was not something I want for my wanderings in the world of the Duke. 

Duke's candy store or stuff to use

On the library part, there is more useful stuff In Maven Central than in Nuget.org. Like .NET,  Java has a community with a lot of  great awesome people that helped me learning to do the Java walk again.
Only the language, the Java language sadly did not change much. Some of the features I was used to in .NET did not exist in 2000 but do exist now:

  • Decorators ocured when I left the Java world. In .NET we know them as Attributes.
  • Streams* LINQ in .NET but without the syntactic sugar.
      Something that deserves a closer look.
  •  Autocloseable with try/catch  Using in .NET
  • Lambdas The same concept in .NET.  I have to investigate the differences.
*Yes I am aware of RX.

Java Beans

Sadly  the most important thing is missing. Java does not have is  have syntactic sugar for properties.
To Java programmers I say: try another language, C#, F#, Scala and see for yourself what is missing.

Back in In 1998 I did an internship at a large defence contractor in the Netherlands investigating the then new concept Java Beans. Core parts of Bean definition:
  • Have default constructor, 
  • have a getter function to get a property, e.g. 'String getName();'
  • have a  'void' setter function to set a property, e.g. 'void setName(String value);'  
To make it more interesting there were PropertyChangeListener en VetoableChangelistener.
 At that time we had a beta of  IBM Visual Age, the predecessor of Eclipse. It allowed graphical construction of your application with beans by drawing lines between them. It was a great tool to demonstrate the concept. However drawing lines does not scale well with realistic applications with many relations. Today's IDEs Like Eclipse, Android Studio or Visual Studio still allow the composition of  GUI and non GUI components but drawing lines to express relations is not used anymore. Short conclusion: Using beans is beautiful.

My first Bean Generator

At the the end of 1998 I started with my master thesis at the same company. With that thesis came writing a prototype compiler for a specification language I designed. The language is not important. I used a Java based compiler generator to get the Abstract Syntax Tree(AST) of my language. For analyzing/compiling the tree into a result I used a lot of Java Beans. At the end I used a Sed based script that generated the beans for me from a text file:
  • First line is the class
  • next lines are properties .
  • First word is the type.
  • Second word is the name.
  • New line separates current from the next bean.
I used a few variations of the script to generate both simple beans and beans with PropertChangeListener and VetoableChangeListener interfaces. 
Writing/generating this many beans seeded my dislike of the Java programming language.

I come back to beans in another blogpost

Java EE

I missed the start of Java EE or J2EE as it was called in the early 2000's. when SOA, XML and SOAP were hot items. At that time I was doing a lot of quick prototyping and Java EE and SOAP were complex beasts I did not need. I used XML for configuration files and messaging. That saved time writing parsers.

Now 2016 I am developing with Java EE. Java EE has changed from an ugly duck to a mature beautiful swan. Some say it is already legacy but I consider it useful proven technology. It provides you with: security, scalability, persistence, logging,caching, dependency injection, REST/SOAP based web services and more stuff application programmers often get wrong when they do it  themselves. It provides you with the tools to write business logic in AOP untangled style: Readable, Maintainable and Reliable.

I Really like the Context and Dependency Injection(CDI) framework in in Java EE and will come back to that in a later post.

Other Stuff

Recently I also assisted in Android development. Android used the Java language but it has it's own set of rules I am still discovering the exciting world of app development. At the moment Consider myself to be not knowledgeable to say much about it. Maybe in a later post.

In .NET the Visual Studio IDE is dominant. Some hipsters use vi, emacs or whatever but most professionals use Visual Studio which imho is a good but BIG IDE. In the Java world there is not a dominant IDE. Well for Android you have Android Studio, but for Java EE development people use Eclipse, IntelliJ, Netbeans or their favorite programmer's editor. I am still in a 'who moved my cheese phase' rediscovering Eclipse and discovering Android Studio. For know I think Visual Studio is still the better IDE. I am aware that Microsoft 'supports' Java coding with Visual Studio but they enforce an old JDK on you.

Next posts

The next posts will be on various topics. At the moment I think about:
  • Java Beans
  • Java EE CDI
  • Using final
  • Java Streams
After that I want to investigate building datamining E-Books using Scala, Java-EE, ElasticSearch and Neo4J. 

If you have questions or remarks please do contact me.