Contribute to help us improve!
Are there edge cases or problems that we didn't consider? Is there a technical pitfall that we should add? Did we miss a comma in a sentence?
If you have any input for us, we would love to hear from you and appreciate every contribution. Our goal is to learn from projects for projects such that nobody has to reinvent the wheel.
Let's collect our experiences together to make room to explore the novel!
To contribute click on Contribute to this page on the toolbar.
Coding Conventions
-
Follow Oracle Naming Conventions
-
Follow the Google Java Style.
-
Establish static code analysis using SonarQube and related tools such as Checkstyle to verify it. (Configuration files are broadly available)
Naming
-
Use short but speaking names.
-
Use Latin alphanumeric ASCII characters and common technical separator (e.g. underscore).
-
For package segments and type names prefer singular forms. Only use plural forms when there is no singular or it is really semantically required.
-
Names of classes, interfaces, enums or annotations should be unique within your project unless intentionally desired.
-
Avoid artificial naming constructs such as prefixes (
I*
) or suffixes (*IF
) for interfaces. -
Use CamelCase even for abbreviations (
XmlUtil
instead ofXMLUtil
). -
Names of Generics should be easy to understand.
-
Follow the common rule
E=Element
,T=Type
,K=Key
,V=Value
. -
Use longer names for more specific cases such as
ID
,DTO
orENTITY
. -
Use capitalized naming helps to distinguish a generic type from a regular class.
-
Code-Documentation
-
APIs are properly documented with JavaDoc.
-
In Javadoc express information not already available in the signature.
-
{@link}
tags in JavaDoc make it more expressive. -
Describe how to use the type or method and not the implementation.
-
Implementation details should be documented inline in complex cases.
-
Use
@Override
instead of{@inheritDoc}
. Since Java 1.5@Override
annotation inherits{@inheritDoc}
.
Prefer general API
-
Do not bind your code to implementations such as
Vector
orArrayList
instead ofList
. -
Use
Collection
instead ofList
orSet
where the difference does not matter. -
Consider
Collection<? extends Foo>
whenFoo
is an interface or super-class.
Catching and handling Exceptions
When catching exceptions always ensure the following:
-
Never call
printStackTrace()
method on an exception. -
Either log or wrap and re-throw the entire catched exception. Do not do both.
-
When wrapping and re-throwing an exception ensure that the catched exception is passed as cause.
-
When logging an exception ensure that the entire exception is passed as argument to the logger. (See the throwable argument in logback).
-
Closing Resources
Resources such as streams or transactions need to be handled properly:
-
Do not deal with such resources manually where possible. (E.g. @Transactional over manual transaction handling where possible).
-
Use
try-with-resources
statement.
Encoding
-
Whenever possible prefer unicode (UTF-8 or better) as encoding.
-
Do not cast from
byte
tochar
. -
Always explicitly use an according western locale (e.g.
toLowerCase(Locale.US)
). See the following discussion on stackoverflow. -
Write your code independent from the default encoding (system property
file.encoding
).-
Always provide an encoding when you create a
String
frombyte[]
:new String(bytes, encoding)
. -
Always provide an encoding when you create a
Reader
orWriter
:new InputStreamReader(inStream, encoding)
.
-
Prefer primitive boolean
-
Avoid using the object type
Boolean
.
// bad
public Boolean isEmpty {
return size() == 0;
}
// fine
public boolean isEmpty {
return size() == 0;
}
Be aware of the scopes of CDI classes
-
Context and Dependency Injection (CDI) classes do have a scope that defines their reuse.
-
Do not store state in CDI classes except for documented reasons
For further references on the scopes in spring and quarkus see:
BLOBs
Avoid using byte[]
for BLOBs as this will load them entirely into your memory.
This will cause performance issues or out of memory errors.
Instead, use streams when dealing with BLOBs.
Optionals
-
Do not use
Optional
for every parameter or result to express that it may benull
. -
Use
@Nullable`or `@NotNull
to clarify the expectation.
Further good practices on optionals can be found here:
Lambdas and Streams
Basic good practices are described here: https://www.baeldung.com/java-8-lambda-expressions-tips
Additionally, the following rules should be applied:
Do not use parallel Streams
-
Using
parallelStream()
in general code that will run on server side can have unexpected side effects. -
Performance improvements should be monitored and not blindly adapted.
Do not perform operations on a sub-stream inside a lambda
set.stream().flatMap(x -> x.getChildren().stream().filter(this::isSpecial)).collect(Collectors.toList()); // bad
set.stream().flatMap(x -> x.getChildren().stream()).filter(this::isSpecial).collect(Collectors.toList()); // fine
Code Tasks
Code spots that need some rework can be marked with the following tasks tags.
TODO
Used to mark a piece of code that is not yet complete. A TODO tag is added by the author of the code who is also responsible for completing this task.
// TODO «author» «description»
FIXME
A FIXME tag is added by the author of the code or someone who found a bug he can not fix right now. The «author» who added the FIXME is also responsible for completing this task.
// FIXME «author» «description»
REVIEW
Don’t use REVIEW tags in modern applications! Todays source code management systems usually have a review support. |
A REVIEW tag is added by a reviewer during a code review. The original author of the code is responsible to resolve the REVIEW tag and the reviewer assigns this task to him.
// REVIEW «responsible» («reviewer») «description»