Skip to main content

Java Coding Conventions considered harmful

Tjuvholmen seen from a boat

2.2 Common File Names:
gnumake to build Java projects? ant is considered old-school, so is maven. Who uses make to build WARs, JARs, generate JavaDocs...?

3.1.1 Beginning Comments:
Putting a class name in the comment starting a file? What if I change my mind and rename the class later? And what should that "date" represent? Some people use various placeholders to insert last modification time of a file automatically by version control system. Well, VCS is there to tell you when the file was created or last modified - and modifying the same line over and over again makes merging a huge pain.

4 - Indentation:
Probably the most counterintuitive part of the document. Some prefer spaces, others (including me) - tabs. A matter of taste and team arrangements. But this guide suggests to use both and replace spaces with tabs, sometimes. It's "unspecified". My advice: use tabs and let each developer configure his IDE to have as big or as small indentations as desired.

4.1 Line Length:

80 characters? My laptop can easily fit three times as much. Strive for 120-140 characters in one line, but don't use hard-wraps. Personally I just display vertical margin and the right line length is dictated by readability. BTW here are few examples of classes from various libraries and frameworks:
And we are suppose to fit whole line in 80 characters?

5.1.2 Single-Line Comments:
if (condition) {

    /* Handle the condition. */
if (condition) {


5.1.3 Trailing Comments:
if (a == 2) {
    return TRUE;            /* special case */
} else {
Did you mean (and don't tell me it's less readable, even without comments)?
return a == 2 || isPrime(a);

6.1 Number Per Line:
int level; // indentation level
int size;  // size of table
int indentationLevel;
int tableSize;
Later in that section:
long dbaddr, getDbaddr(); // WRONG!
Sure it's wrong, it doesn't even compile. I'm surprised that "don't put spaces in variable names" is not mentioned as a good practice...

6.3 Placement:
Put declarations only at the beginning of blocks. [...] Don't wait to declare variables until their first use; it can confuse the unwary programmer [...]
int min;            //inclusive
int max;            //exclusive
int distance;
List<String> list;  //one per each item

min = findMin();
max = findMax();
distance = max - min;
list = new ArrayList<>(distance);
And this is how it should be written to avoid confusion:
final int minInclusive = findMin();
final int maxExclusive = findMax();
final int distance = maxExclusive - minInclusive;

7.3 return Statements:
return (size ? size : defaultSize);
Maybe you haven't noticed, but from the context we can tell that both size and defaultSize are of boolean type. That's right, size and defaultSize can be either true or false (!) How counterintuitive is that! From such a document I would expect not only syntactical correctness, but also meaningful code and good practices! Moreover, the expression can be greatly simplified, step-by-step:
size ? size : defaultSize
size ? true : defaultSize
size || defaultSize

7.5 for Statements:
for (initialization; condition; update);
"empty for statement"? Why would you ever use an empty for statement? This is confusing and should be avoided, not encouraged and described in the official language guide.
Bonus quiz: what's the purpose of this code in C?

7.8 switch Statements:
I understand the intentions, but the approach is wrong. Instead of documenting unexpected and error-prone code-fragments, just avoid them. Don't depend on fall through, don't use it at all.

8.1 Blank Lines:
One blank line should always be used in the following circumstances:
  • Between the local variables in a method and its first statement
  • Before a block [...] or single-line [...] comment
  • Between logical sections inside a method to improve readability
Looks like the authors suggest using blank lines to separate "logical sections of a method". Well, I call these sections: "methods". Don't group statements inside methods in blocks, comment them and separate from each other. Instead extract them into separate, well named methods!

8.2 Blank Spaces:
while (d++ = s++) {
This doesn't even compile in Java...

9 - Naming Conventions (only in PDF version):
char *cp;
A good name for a char pointer in Java is cp. Wait, WAT? char pointer in Java?

10.1 Providing Access to Instance and Class Variables:
Don't make any instance or class variable public without good reason.

10.4 Variable Assignments:

10.5.2 Returning Values:
if (booleanExpression) {
    return true;
} else {
    return false;
should instead be written as
return booleanExpression;
Holy cow, I AGREE!

It's not that the official Code Conventions for the Java Programming Language are completely wrong. They are just outdated and obsolete. In the second decade of the XXI century we have better hardware, deeper understanding of code quality and more modern sources of wisdom. Code Conventions... were last published in 1999, they are heavily inspired by C language, unaware of billions of lines of code yet to be written by millions of developers. Code conventions should emerge over time, just like design patterns, rather than be given explicitly. So please, don't quote or follow advices from official guide ever again.


  1. 6.3 Package private field - but what about unit testing? I read this article ( and author uses such access to inject mocks (section: Unit Testing Java EE 6 with Some Mockito). Is there a better way?

    This Oracle document is really horrible :-), why they didn't remove it?

    1. I don't particularly like opening a class to make it testable. If you have to, check out @VisibleForTesting annotation. But I believe it's against the principle of dependency injection - and is ugly. Either use setters to inject mocks or constructor injection (which I love in Scala).

  2. I found that Bien is promoting package-private:, but I think that constructor injection is good solution, thanks. Setters - that's the ugliest way in my opinion.

    1. As much as I admire Adam Bien, I can't agree with making fields package-private just for testing. If it was a bit easier in Spring and Java, I would use constructor injection for everything. I believe that's the way DI should always be implemented.

    2. I don't like to have test-specific code in my production code, so the @VisibleForTesting annotation or a setter just for testing would not be my choice. I'd rather use Spring's ReflectionTestUtil.setField() method to inject the mock or Mockito's @InjectMocks. I would keep away from package-private fields.

  3. Nice post - That gave me a good laugh: "I'm surprised that "don't put spaces in variable names" is not mentioned as a good practice"

  4. Your sarcastic comments about 5.1.2 and 5.1.3 ignore the true message. It’s difficult to create short code snippets that need meaningful comments.

    1. I partially agree, both simple and non-trivial code samples are hard to find. But in this particular case there are plenty of good examples. E.g. look at java.util.Arrays.mergeSort() in JDK 6:

      // Insertion sort on smallest arrays
      if (length < INSERTIONSORT_THRESHOLD) {

      However I would place a different comment: "Use insertion sort on smallest arrays because it's faster". But it only proves the point that better code samples are possible.


    java examples


Post a Comment