Last Updated:

How to Write Good Java Code

Introduction to Java Code

You already know a lot about the syntax of Java, but that's not exactly what professional programming is all about. What makes Java programs "good"?

There are probably as many answers to this question as there are professional Java programmers. But I have a few suggestions that I'm sure most professional Java programmers would agree with, and that improve the quality of Java code.

Truth be told, I'm a proponent of agile techniques like Extreme Programming (XP), so a lot of my understanding of "good" code is shaped by the agile community and, in particular, the principles of XP. However, I believe that most experienced professional Java programmers would agree with the advice I will give in this section.

Make classes small

In this tutorial, you created a simple Class Adult. Even after we moved the main() method to another class, Adult had over 100 lines of code. It has over 20 methods, and doesn't really do much work compared to the many professionally created classes you're probably seeing (and creating). It's a small class.

It is not uncommon to see classes with a number of methods ranging from 50 to 100. What makes them worse than classes that have fewer methods? Probably nothing. There should be as many methods as you need. If you need multiple helper methods that do basically the same job but take different parameters (like our addMoney() methods), this is a great option. Just limit the list of methods to only those that are really needed, nothing more.

Typically, a class with a very large number of methods contains something that is not characteristic of it, because such a giant object does too much. In his book Refactoring, Martin Fowler calls this "Foreign Method code smell." If you have an object with 100 methods, you should think carefully about whether this one object is actually a combination of several objects. Large classes usually lag behind in school. The same goes for Java code.

Make methods small

Small methods are also preferred, as are small classes, and for the same reasons.

One of the frustrations that experienced OO programmers have about the Java language is that it gives the broad masses of users an object-oriented approach, but does not teach them how to use it correctly. In other words, it gives enough rope to hang yourself (though less than C++ gives). You can usually see this in a class with a five-mile-long main() method, or in a single method called doIt().

Just because you can put all your code into one method of your class doesn't mean you should. The Java language has more syntactic frills than most other OO languages, so some verbosity is necessary, but don't overuse it.

Imagine for a moment such very long methods. Flipping through dozens of pages of code on the screen to understand what's going on makes it difficult to understand! What does the method do? You have to drink a big cup of coffee and study the code for a few hours in order to understand it. The small, even tiny, method is an easily digestible piece of code. Efficiency at runtime is not the reason for creating small methods. The real prize is readability. This makes your code easy to maintain and modify when adding new functionality.

Limit each method to the performance of a single action.

Name the methods correctly

The best coding scheme I've ever come across (and I've forgotten the source) is called: intent-detecting method names. Which of the following two methods is easier to understand at a glance?

  • a()
  • computeCommission()

The answer should be obvious. For some reason, programmers have an antipathy to long names. Of course, an absurdly long name can be awkward, but the length of the name that is sufficient to understand is usually not absurdly large. I have no problem with a method name such as aReallyLongMethodNameThatIsAbsolutelyClear(). But if at three o'clock in the morning, trying to understand why my program does not work, I meet a method called a(), then I want to hit someone.

Spend a few minutes on a very descriptive method name (if possible), come up with method names so that your code reads more like English text, even if it means adding additional helper methods to get the job done. For example, consider adding a helper method to make the following code more readable:

The isEmpty() method of the ArrayList object is useful in itself, but this condition in our if expression can be improved by using the Adult method named hasMoney(), which looks like this:

Now our if expression is more like English:

This technique is simple and perhaps trivial in this case, but it is strikingly effective when the code becomes more complex.

Minimize the number of classes

One of the rules of simple design in XP is to achieve the goal with the minimum required number of classes. If you need another class, of course, add it. If another class would simplify your code or make it easier to express your intent, add a class. But there's no reason to have classes just to have them.

More often than not, earlier versions of a project have fewer classes than the final version, but it's usually easier to refactor to split your code into more classes than to combine them. If you have a class with a large number of methods, analyze it and determine if it contains another object before it manifests itself explicitly. If so, create a new object.

In almost all of my Java projects, no one was afraid to create classes, but we were also constantly trying to reduce the number of classes without making our intentions any less clear.

Minimize comments

I once wrote extensive commentary on my programs. You could read them like a book. Then I got a little smarter.

Every programming science program, every programming book, and lots of programmers, I'm sure, advise you to comment on your code. In some cases, comments are helpful. In many cases, they make the code more difficult to maintain. Think about what you should do when the code changes. Is there a comment in this place? If there is, you'd better change the comment, otherwise it will be outdated and may not describe the code at all over time. Based on my experience, this doubles your time to maintain the program.

My rule of thumb is that if the code is so hard to read and understand that a comment is needed, I should make it understandable enough that the comment is not needed. The code may be too long, or do too much. If so, I'm simplifying it. It can be too confusing. If so, I'll add helper methods to make it more understandable.

In fact, in three years of co-programming in Java with members of the same team, I can count the number of comments I've written on my fingers and toes. Write clear code! If you need a general description of what the system or any particular component of it does, write a short document for this.

Verbose comments are usually harder to maintain, don't express your intentions the way a small, well-written method does, and quickly become obsolete. Don't get addicted to comments.

Use a unified style

The coding style actually depends on what is necessary and acceptable in your environment. I don't even know a style that I can call "typical." It often depends on personal taste. For example, here's some code snippet that causes me to convulse until I change it:

Why does it annoy me? Because I'm personally against a coding style that adds lines of code that I don't think are necessary. The Java compiler interprets the following code similarly to the previous one, and I saved a few lines:

There is no way to be "right" or "wrong." One is simply shorter than the other. What happens when I have to code with someone who prefers the first form? We talk about it, choose the coding style we're going to stick to, then fix it. The only rule for all occasions is unification. If someone working on a project uses a different style, reading the code will become difficult. Choose a style and don't change it.

Avoid using switch operators

Some Java programmers like switch expressions. I thought they were good, but then I realized that the switch expression is actually just a set of if expressions; this usually means that conditional logic appears in my code in more than one place. This is code duplication, which is unacceptable. Why? Because having the same code in multiple places makes it difficult to change. If I have the same switch in three places and need to change one option, I have to change three code snippets.

Now, can you refactor the code so that there is only one switch expression? It's cool! I have nothing against its use. In some situations, the switch expression is more understandable than nested if . But if you see that it appears in several places – this is a problem that you have to solve. An easy way to prevent it from happening is to avoid the switch expression until it is the best way to get the job done. My experience is that this rarely happens.

Be open

I left the most dubious recommendations at the end. Inhale deeply.

I believe it will not be a mistake to make all your methods public. Instance variables must have the protected specifier.

Naturally, many professional programmers shudder at this thought, because if everything is open, anyone can change anything, possibly unauthorized. In a world where everything is open, you have to depend on the discipline of the programmer to ensure that people don't have access to things they shouldn't have access to, and when they shouldn't.

But in the life of a programmer, there are few situations more disappointing than the desire to turn to a variable or method that he does not see. When you restrict access to something in your code, assuming others shouldn't have it, you assume you're omniscient. More often than not, this is a dangerous assumption.

This kind of frustration often comes when using someone else's code. You can see a method that does exactly what you need, but it's not available. Sometimes there are good reasons for this, so it makes sense to limit availability. However, sometimes the only reason that a method isn't listed as public is because the guys who wrote the code thought, "No one will ever even need to address it." Or maybe they thought, "No one should turn to him because...", with no good reason at all. Very often, people use the keyword private just because it exists. Don't do that.

Specify methods as public and variables as protected unless you have a good reason to restrict access.

In the footsteps of Fowler

Now you know how to create good Java code and how to keep it good.

The best book on this topic is Martin Fowler's Refactoring. It's even easy to read. Refactoring means redesigning existing code without changing its results. Fowler talks about "code smells" that require refactoring, and takes a very close look at the various techniques for fixing them.

In my opinion, refactoring and the ability to write code in the style of test-first (first testing) is the most important skill that novice programmers should master. If every programmer were good at both of these skills, it would revolutionize the industry. If you master them perfectly, it will be easier to get a job, since you will be able to achieve better results than most of your associates.

Writing Java code is relatively easy. Writing good Java code is a skill. Strive to become a master.