Go Ahead: Next Generation Java Programming Style

Many companies and developers move away from Java to new languages: Ruby, Python, Groovy, Erlang, Scala. You might be trapped with Java.

Even if you've trapped, you can change your programming style and reap some of the benefits of those new languages. In the last 15 years Java programming style has changed significantly:

  1. Final is your new love: More and more Java developers in the teams I've worked with, started to use final. Making variables final prevents changing those values. Most often, if you reasign a value, it's a bug or you should use a new variable. Final prevents bugs and makes code easier to read and understand. Make everything immutable.

    I've written more about this topic in "All variables in Java must be final".

  2. No setters. Many Java developers automatically - sometimes with the evil help of an IDE - write setters for all fields in their classes. You should not use setters. Think about each setter you want to write, are they really necessary for your fields? Better create new copies of your objects if values change. And try to write code without getters either. Tell, don't ask tells you more about the concept.
  3. Do not use loops for list operations. Learning from functional languages, looping isn't the best way to work on collections. Suppose we want to filter a list of persons to those who can drink beer. The loop versions looks like:

    This can - even in Java - be rewritten to a more a functional programming style. For example using Google collections filter:

    As remarked by Dave Jarvis, I should have dropped the getter, and he's right ;-)

    which would lead to better code down the road:

    The predicate version is slightly larger, but consists of two parts. Each one is easier to understand. While the loop version gets unreadable fast with new requirements, the functional version can easily be combined,

    More on this at the Metaphysical Developer.

  4. Use one liners: Write concise code. Java is a noisy language. But don't make it noiser as it needs to be. Instead of


    IDEA and possibly other IDEs can keep oneliners formatted as oneliners, if you tell them so.

  5. Use many, many objects with many interfaces. Domain driven design currently makes a big splash. A class should be splitted into many roles, implementing many interfaces. This way the class is reusable.

    Methods should be written to only work on roles, not classes. This way methods can work on more objects. Another benefit is lower coupling.

    I've written more about that in "Never, never, never use String in Java ".

  6. Use Erlang-Style Concurrency. The Java concurrency primitives like locks and synchronized have been proven to be too low level and often to hard to use. There are better ways to write concurrent code. Erlang Style concurrency is one of them - in Java there are many ways to achive this in Java - I've written about them here. Newer ones are Akka and Actorom. You can also use Join/Fork or the myriad of data structures in java.util.concurrent.
  7. Use Fluent Interfaces. Fluent interfaces can make your code much more readable and shorter. A very good example is the MapMaker API in Google Collections:

  8. Data Transfer Objects without setters and getters. If you have simple data holders or data transfer objects, don't write boiler plate code with getters and setters. I know this is heresy in Java, but just use public fields. Instead of


    Refactoring is easy, should you need it. If you do not control all the code and it's usage, you might need to be more careful though.

This tips lead to better Java code. Try them in your next Java class. What do you think? I'd like to hear how your Java coding style has changed in the last 10 years.

Uodate: Some thoughts to Cedrics thoughts.

As the author of the post, your thoughts are appreciated, some of mine:

"Besides, it's convenient to be able to mutate object if you want to use pools."

No setters doesn't mean you can't mutate objects, it's just that plain setters are not object oriented thinking. How about stop() vs. setStop(true);

"I think the first example is more readable than the second one that uses Predicates."

I think your assumptions are wrong. Loops are procedural code, while Predicates are, encapsulated, reusable, understandable objects. Nothing to do with functional programming, plain OO - it's only ursurped by functional programming, therefor I refer to it as FP.

Dynamic typing as safe as static typing is based on wrong assumption

Update 3: Because I got stalked, I change the tilte of the post from "The unit testing lie aka dynamic typing testing lie". I like this blog, but it's not worth it. The view that dynamic typing and static are equally safe is based on the assumption that dynamic developers do more unit testing (what the compiler otherwise does) than static developers to ensure safety.

Update 1: Thanks to Graeme. I have been unclear with my post. The lie I'm talking aboutis that there is no problem with dynamic languages or a difference between dynamic languages and static languages concerning type bugs you can write unit test, suggesting that developers really write unit tests to cover type checks. All would be good if people write tests. Josh as someone who fixes Rails projects says that he often sees not enough or no unit tests in the Rails projects they are called to fix. If you use dynamic languages and have >90% test coverage including duck typing, you're safe and this post does not apply

Update 2: If you want to make a sensible comment, you could say "Lie is an exaggeration, could it be a logic fallacy?" and I would reply "Saying knowingly not the truth is lying". Or you could say "From the 37 projects in [Dynamic Language Of Your Choice] which I have investigated, the lowest code coverage with unit testing was 80%" and I would reply "Thanks for the facts, seems contrary to the facts in my post unit testing is widespread in dynamic language projects" and change the title. Or you could give your opinion about any topic you wish, attack me and spare me facts.

Stumbling upon one of the very best articles about web programming for some time: Rails Worst Practices: 13 Coding Nightmares You Should Avoid by Josh Symonds. One of the experiences Josh is that developers don't do - enough - unit testing:

[Testing] This should probably be higher since it's one of the most annoying things about picking up an existing codebase. A lot of the code we get isn't well tested, or even tested at all. Untested code is very very difficult to alter: you're not sure if the small change you're making will break functionality out in the middle of nowhere, and you have no way of testing it without following through the application flow every time you make a change.

When discussing dynamic vs. static languages, the arguments for not needing static type checks are based on more unit tests.

The blog post says: Nada, developers don't test. [1]

This reflects my experience. Developers don't test. They do test after they got a bloody nose several times, best a bug lost some money, lost bookings or orders or the plattform was down. Then developers literally yearn for more security. They write tests if you tell them again and again (or they are very very good). And you need hard coverage metrics and goals - even if it's 100% (some won't agree). Otherwise they are over-optimistic, over-confident and always under deadline preasure. Unit tests are hard to explain to business users and managers - they can be explained but often developers do a bad job at explaining them.

I was astonished by the claim that everything is fine in Rails-land and developers, contrary to most of their brethren, do extensive (even more than for static languages) unit testing. Seems to be mostly a myth - especially with more Rails developers as the experience level goes down. You can have a community of 1000 top coders, but not of 100.000 top coders, there aren't enough.

There is much more interesting insight in the article:

Chubby Controllers Must Die
There should be no business logic in a controller.

It's not about Rails. Every project and every web framework I've seen has been abused by developers. They put code into parts where they should not. In Struts, in JSF, all the time. Developers don't change and a web framework won't help. Strict coding practices and reviews help.

NEVER Assume You Don't Have Nil
Maybe you assume that your ActiveRecord object has an association on it, like address. So you innocently type user.address.telephone and blam! Your application blows up because address was, in fact, nil.

Again the same experience. The biggest problem in Java are Null Pointer Exceptions, people don't check for null often enough. The don't use Either style error checking either (ha!). And Java doesn't support safe dereferencing yet:

Null dereference expressions - Null checks with '?' syntax similar to Groovy... lettign developers avoid a nest of null checks.

Another one from the post:

Check ActiveSupport (and other Rails/Ruby classes) FIRST
I see a ton of methods that already exist in ActiveSupport that are hand-coded from scratch. Stuff like Time#beginning_of_week and pluralize pops right to mind. Also there are a lot of people who do scratch versions of time_ago_in_words and number_to_currency (two of the most helpful ActionView Helpers)

Would easily translate to "Check commons" in Java. Or check the JDK. Especially reuse JDK code when someone asks you this in an interview

All in all, excellent post, go read it.

Thanks for listening. As ever, please do share your thoughts and additional tips in the comments below, or on your own blog (I have trackbacks enabled).

[1] All generalizations outside of physics, mathematics and chemestry are wrong. Without them one cannot make meaningful descriptions about the world. This should read most developers and "test enough".

Because people are not accustomed to the discussion, some entry points into the dynamic vs. static discussion, how static typing is just a kind of test and how unit tests are better than static typing.

About using unit tests to find usual compiler errors by Steve:

But the argument that I'm making is NOT that compilers don't occasionally help you catch errors. The argument that I'm making is that you're gonna catch the errors one way or the other. Especially if you've got unit tests, or QA or whatever.

About dynamic language users doing more unit tests:

People who use languages with strong static type systems seem to do a lot less unit testing.

In a paragraph about "The strong vs. weak typing issue really gets people worked up.":

We can achieve sufficient reliability through a combination of rigorous unit testing and agile development practices.

About useful code coverage for Rails by David:

In terms of new features, we've been able to add new features to the lift code with fewer defects than with the Rails code. Our Rails code had 70% code coverage. We discovered that anything shy of 95% code coverage with Rails means that type-os turn into runtime failures. We do not have any code coverage metrics for the lift code, but we have seen only 1 defect that's been checked in in the 2 weeks since we started using lift (vs. an average of 1 defect per checkin with the Rails code.)

About how unit testing helps to find bugs in your code when using Groovy (that otherwise the type system finds):

"It might be scary to do away with all of your static typing and compile time checking at first. [...] You should make all efforts to use unit tests to verify your intended behavior."

About the importance of unit tests in the Rails community by Eric:

"The Rails framework and the Rails community are both built on a culture of good programming habits.
[...] Unit tests? Built in and highly encouraged.

A variant of the argument about testing, which says: Static typing doesn't help you much, because it doesn't verify all behavior, you need unit test nevertheless. Suggesting that people do unit tests, by Bruce:

The only guarantee of correctness, regardless of whether your language is strongly or weakly typed, is whether it passes all the tests that define the correctness of your program. And you have to write some of those tests yourself. These, of course, are unit tests.

This should help as a starting point in the static vs. dynamic typing discussion. Unit tests are a great invention, I suggest you have 100% CC coverage. But don't read those comments on dynamic languages and feel safe. You need to write tests, otherwise they will not help you.

TIOBE Index: Java on top, Python up, Ruby down and no longer in Top 10

Looked at the current November 2008 TIOBE programming language index, found via Cedrics Twitter. Java still on top, very slow slide, Ruby down by 2 places, no longer under the Top 10, C++, C# and especially Python up, PHP still 5th, Erlang at 31st, Scala at 43rd ;-) F# not listed in Top 100.

Other interesting tidbits:
"The object-oriented paradigm is at an all time high with 57.9%. The popularity of dynamically typed languages seems to be stabilizing."

(after some big increases for dynamically typed languages since 2002)