-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Coding Style Java
Miklas Boskamp edited this page Feb 26, 2024
·
11 revisions
- These are the coding style guidelines that should be used for writing Java code
- Rules must always be followed
- Best practices should be followed, but exceptions can be made
- Indentation is two spaces
- Indentation for chaining method calls on new lines is four spaces
- No trailing whitespace; no whitespace on empty lines
- Lines of code must not exceed 120 characters
- If lines with method signatures exceed 120 characters, each parameter must be on a new line
- Bracket placement: Kernighan and Ritchie style ("Egyptian brackets") for non-empty blocks and block-like constructs; plus: opening brackets of classes and methods go on the same line as the declaration
return new MyClass() {
@Override
public void method() {
if (condition()) {
try {
something();
} catch (ProblemException e) {
recover();
}
} else if (otherCondition()) {
somethingElse();
} else {
lastThing();
}
}
};
- Local variables must be declared close to their first usage, not at the beginning of the block
- Names of static final member variables (class fields) are uppercase with words separated by underscores ("_"); All other variable names are camel case
- On declaring variables (local or global), always use the highest possible type that your implementation still can handle, e. g. ...
- when declaring a map, prefer the
Map
interface over a concrete implementation type likeHashMap
-
Collection
vs.List
vs.ArrayList
- when declaring a map, prefer the
- Files must be encoded in UTF-8
- In our main codebase (i.e. no tests), modifier
private
is not allowed for fields and methods;protected
should be used instead; this allows our users to work around problems or extend the engine easier - Always use
@Override
when you override or implement a method - Do not use
@author
tags; Do not remove existing tags - Avoid redundant interface modifiers: public (methods / fields), static (fields) & final (fields)
- Annotations placement:
- Methods, fields and classes: Above the declaration, one annotation per line
- Method parameters and local variables: On the same line
- Always use a default branch in switch-case statements, may be omitted for switch statements on enums if all values are used
- Use the recommended order of modifiers:
public protected private abstract default static final transient volatile synchronized native strictfp
We consider the var
keyword a good match in the following cases:
- There is no need to backport the code to 7.19 and earlier (var is not supported there)
- New Tests or refactoring of existing code
- Try-with-resources blocks
- Initialization of maps, lists, collections, etc, where the right side of the assignment conveys the type
- Common boilerplate scenarios, e.g. setup / tearDown methods, iterating over generic types, creating and populating a collection
- Small methods (2 - 10 lines) where the name conveys intent, usage, and behavior is simple.
- String literal references
- Reduce long class names that add more noise to the overall readability than value, e.g:
CommandInvocationContext commandInvocationContext = new CommandInvocationContext(command, processEngineConfiguration, openNew);
// can be replaced with
var commandInvocationContext = new CommandInvocationContext(command, processEngineConfiguration, openNew);
Try to avoid using the var
keyword in the following scenarios:
- Variable assignments that include a function return call where the reader cannot infer the type from the function's name, e.g.:
var x = resultOfFunction() // not allowed because the reader has to rely on the function to infer the type.
var instance = runtimeService.startProcessInstanceById // OK; the type is conceptually ProcessInstance
var bpmnString = Bpmn.convertToString(modelInstance); // OK; the type String is conveyed by the function name
General Guidelines:
- Use
var
as a guide to choose better naming when the type is not that important - Code should be clear from local reasoning
- Minimize the scope of local variables
- Code readability should not depend on IDEs
- Consider var when the initializer provides enough context for the reader
- Use Diamond Operator (
List<String> list = new ArrayList<>();
), try-with-resources, underscores in numeric literals when it improves readability
- Do not use star imports
- All unused imports must be removed
- Static imports in a single block
- Non-static imports in a single block, divided from static imports by a blank line
- Import order consistent for all IDEs
- Everyone should commit the same line endings
- Consistent placement of new lines of a source file
- Do not push
TODO
orFIXME
comments to master. Instead, either fix it immediately or create a JIRA issue that describes the user impact. - Add Javadoc comments to new
ProcessEngineConfigurationImpl
andProcessEngineConfiguration
properties to make the purpose of the property visible to users and developers without the need of diving into code.
- Make setters in
ProcessEngineConfigurationImpl
andProcessEngineConfiguration
fluent
- Within the same source file, the ordering of annotations should be consistent
- Consider writing Javadoc for non-trivial code that you encounter. This can be new code or already existing code that you inspected for a current task.
- When extending the Java API (e.g. adding a new parameter to a query, or a new property to a response), make sure to also reflect this in the REST API.
- No IDE warnings should be committed
- Eclipse/IntelliJ settings that produce the same amount of warnings should be used