Java in view of clean code¶
- Published at
May 18, 2020
- Author
Erlend ter Maat
Out of curiosity I picked up learning a programming language that I’ve been able to ignore for a long time. Java!
To get an idea about the limits of a language I usually look up a koans project about the subject. For Java it appeared to me that this project was most up to date: https://github.com/matyb/java-koans
Clean code¶
Question¶
Wait… Clean code? Does that have something to do with programming language? How about skills?
Answer¶
Of course! It is true that a skilled developer would write more clean code that a less skilled developer. In whatever language available.
It would be possible to write any application in any language, but not all languages are as effective, and some languages (Assembler) are intended to be uneasy to read by humans, and therefore very hard to keep clean. How will this work out for Java?
I noticed…¶
I’m used to typeless languages and I’m sceptical to the recent development of PHP to become more and more typed. But when you do typing, let’s do it good. That is what Java is about, I thought. This prejudice resulted in interesting discoveries at more then 1 occasion.
AboutLoops.java¶
I consider “goto” (and labels) as characteristic for non OO. At the best it is not clean OO, at worst it smells like unexpected behaviour. In the loops section an interesting inconsistency, from a clean code perspective, was introduced: Java supports it.
@Koan
public void forLoopBreakLabel() {
int count = 0;
outerLabel:
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
count++;
if (count > 2) {
break outerLabel;
}
}
count += 10;
}
// What does break with a label mean?
// What gets executed? Where does the program flow continue?
assertEquals(count, __);
}
Reading top to bottom I expected break to rewind to the outerLabel position. But… It does not. It break out of the 2 loops. As a readable alternative I would move the double loop to a separate method and use a return statement to mark the end of processing.
AboutObjects.java¶
@Koan
public void toStringIsTestedForNullWhenInvokedImplicitly() {
String string = "string";
assertEquals(string + null, "stringnull");
}
Functionally, when you add null (nothing) to a string, as a result the string is unchanged. But because null is casted to string the word ‘null’ is appended. Something to keep in mind while working with strings.
AboutInnerClasses.java¶
public class AboutInnerClasses {
// ...
private int x = 10;
static class StaticInnerClass {
public int importantNumber() {
return x;
}
}
@Koan
public void staticInnerClass() {
StaticInnerClass someObject = new StaticInnerClass();
assertEquals(someObject.importantNumber(), __);
// What happens if you try to access 'x' or 'theAnswer'
// from the outer class?
// EM: Compile error: non-static variable x cannot be
// referenced from a static context.
// What does this mean for static inner classes?
// EM: static members can't access non-static members
// and vica versa.
// Try to create a sub package of this package which is
// named 'StaticInnerClass'. Does it work? Why not?
// EM: Sub-packages are about organization of classes.
// It does not change scope or static/non-static
// interaction.
}
// ...
}
This example, and others in this chapter, is interesting because nesting of classes is implemented in great detail. However. Nesting of classes, in my humble opinion, often does not help in writing readable code. I can imagine that I would want ot write a small tool in class-like fashion. Then I’d rather put it in a sub-package. But I don’t expect a functional relation between classes in packages and subpackages. Correct me if I’m wrong.
Conclusion¶
Since Java is around for some time (June 1991) and can be used on many platforms for many types of applications I expect a lot of things that “I’m not gonna need”. But that does not mean at all that the language forces me to write code that I’m not gonna need.
In view of how easy it is to learn the language: The strict typing forces you to work in a certain way with objects where typeless languages are more forgiving. I like about the language that it compiles the software. I take that as a free test that notifies you about syntax errors.
The language gives developers plenty of freedom to choose names for methods and properties. In general it is good to follow. So in view of clean code: It can be done!