Coding Rules (Java)
This article is based on the author's own research and testing and does not guarantee the accuracy or completeness of the information provided.
If you use the information in this article, you do so at your own risk. The author assumes no responsibility for any issues or damages resulting from its use.

Personal coding rules I have compiled through Java development. These rules also reflect experience in product development in corporate environments.
Introduction
One indicator of whether code is good or not is whether it is "easy for other people to understand." Whether code is easy to understand is determined by various factors, including not only the clarity of the logic, but also formatting and the conventional use of APIs.
When coding in a project consisting of multiple people, it is necessary to be conscious of whether the code is easy for others to understand as well.
Prioritizing readability is also beneficial for myself when I need to maintain code that I may not have touched for a long time.
This document describes coding rules and recommendations for application development projects using Java as the development language.
This does not mean that "you only need to pay attention to what is written here." Please code flexibly while keeping in mind the perspective of writing code that is easy to understand.
This document was created as a draft, so it is intended for reference only. It is recommended that the rules be modified as appropriate for each project and its users.
Files
Each public class should be placed in a file named after that class.
- Do not write multiple public classes in a single file.
- A non-public class that is not used by other classes may be included in the file of the public class that uses it (as an inner class). However, inner classes should not be used in principle.
The file encoding should be UTF-8.
File Hierarchy
Follow Maven's standard directory layout.
Maven has been used as a de facto standard build tool for Java for a long time, and using Maven's standard directory layout makes the project structure easy for many Java developers to understand.
Naming Conventions
Uppercase and Lowercase
Java is case-sensitive, but do not write code that distinguishes identifiers solely by differences in uppercase and lowercase letters.
Bad example)
private int num;
private int Num;
Good example)
private int cartNumber;
private int productNumber;
Package Names
- Use strings consisting of lowercase English letters separated by "." and include a name representing the application/project.
- If the application is intended to be publicly released, basically include the domain name.
Example) com.mosaos.projectname
Class Names
Use UpperCamelCase.
Example) UpperCamelCase
Exception Class Names
Use a class name ending in Exception.
Interface Names
Follow the same naming convention as class names.
Implementation Class Names
If it is necessary to distinguish an implementation class from its interface, append Impl to the end.
Abstract Class Names
If there is no suitable name, start with Abstract and use a name that suggests the subclasses.
Do not create abstract classes unnecessarily.
Consider carefully whether an abstract class is really necessary, except when there is a clear purpose such as the Template pattern.
Avoid creating abstract classes (using inheritance) for reasons such as the following:
Inheritance for sharing methods
- It becomes difficult to modify or add functionality to common methods.
- Common methods keep being added to the base class, eventually creating a God class.
Inheritance for sharing member variables
- Member variables become difficult to modify because doing so affects derived classes.
Constants (static final)
Use uppercase snake case.
Example) UPPER_SNAKE_CASE
Method Names
Use lowerCamelCase.
Example) lowerCamelCase
For methods that perform an operation, use a name in the form of verb + object, rather than object + verb.
Bad example) couponGet
Good example) getCoupon
Attribute Access
For methods that retrieve attributes, use the getXxx or isXxx form (xxx is the attribute name).
Attribute Setting
For methods that set attributes, use the setXxx form (xxx is the attribute name).
English and Japanese
Use English as the basic language for all identifiers. In exceptional cases where translating a term into English is difficult, romanized Japanese may also be used. However, whenever possible, create and maintain a terminology dictionary and avoid using different names for the same term.
Naming Symmetry
When naming things, pay attention to the following English word pairs:
- add / remove
- insert / delete
- get / set
- start / stop
- begin / end
- send / receive
- first / last
- get / release
- put / get
- up / down
- show / hide
- source / target
- open / close
- source / destination
- increment / decrement
- lock / unlock
- old / new
- next / previous
Loop Counters
Use i, j, and k for loop counters with a narrow scope.
Variables with a Narrow Scope
Abbreviations may be used for variable names with a narrow scope. However, do not overuse abbreviations to the point that readability is reduced.
Example)
InputStream in = new BufferedInputStream(...);
Meaningful Names
As a general rule, use names whose meaning can be understood from the name itself.
Bad example)
copy(s1, s2);
Good example)
copy(source, destination);
Style
The coding style should follow the style of the JDK source code.
It is similar to the K&R style for the C language, but the opening { of a class/method definition should be written on the same line rather than on a new line.
Use Checkstyle to check the style and automate the process as much as possible.
Comments
As a general rule, write Javadoc comments for public classes and methods.
Write only necessary comments, and keep them concise.
Write comments that explain why something is done.
Write comments before writing the code.
As you will find when you try it, one of the best ways to write good comments is to describe the processing concisely in comments before writing the code.
If the processing consists of multiple steps, write each step as a separate line of comments before starting the implementation.
This ensures that comments are written and also helps ensure that the implementation follows what was described in the comments.Make use of
TODOcomments.
Since IDEs such as Eclipse allow TODOs to be viewed together, useTODOcomments to describe work that should be done later when something remains unfinished due to reasons such as waiting for another person's implementation or waiting for the specification to be finalized. When viewing the list in Eclipse, use theTasks View. In addition to TODO, the following comment tags can be used as task tags.FIXME: A fix is required.XXX: Dangerous! It works, but it is unclear why it works.
There are other tags besides FIXME and XXX, but when using them in Eclipse, you need to add the comments to be used under [Settings] > [Java] > [Compiler] > [Task Tags].
Imports
As a general rule, do not use * in import statements.
Scope
Set appropriate scopes for methods and fields.
Instance Variables
As a general rule, use private scope and write setters/getters as necessary.
For simple setters/getters that only set or retrieve values, use Lombok as appropriate to improve code readability and development efficiency.
Use of Local Variables
Except for entity classes, bean classes, and similar classes, avoid using instance variables as much as possible.
In particular, when using a DI container such as the Spring Framework, certain classes may be instantiated as singletons by default. Therefore, using instance variables carelessly can result in a thread-unsafe implementation.
As a result, a bug may not be detected during unit or integration testing and may only occur in actual production use. In some cases, this can lead to serious problems such as the leakage of personal information, so implement such code with care.
Use of final
Use final appropriately as necessary.
- Classes that should not be inherited
- Methods that should not be overridden
- Variables whose values do not change (or should not change)
Comparison
Use the equals method when comparing objects. Using == is acceptable when you want to compare whether two references refer to the same instance.
Boolean Comparison
Do not compare boolean variables in conditional expressions.
Bad example)
if (isEmpty == true)
Good example)
if (isEmpty)
Loops
Use an enhanced for loop when it can be used.
Referencing Through Interfaces
As a general rule, use interfaces when declaring object references. In particular, the following coding style is sometimes seen when using the Java API, but it is not a good implementation and should be avoided.
Bad example)
ArrayList<Entry> list = new ArrayList<Entry>();
Good example)
List<Entry> list = new ArrayList<Entry>();
Numbers
Use the BigDecimal class appropriately when necessary.
Strictly speaking, arithmetic operations using primitive types or types other than BigDecimal may result in rounding errors.
When exact calculations are required, such as in financial or scientific applications, BigDecimal is suitable.
Try-With-Resources
When using classes that require resource cleanup, such as streams, use try-with-resources whenever possible.
String Concatenation
When performance may be a concern with string concatenation, such as when performing string concatenation inside a loop, use StringBuilder (or StringBuffer).
Use StringBuffer when thread safety is required.
Use of System.out.print
Replace it with a logging API.
Except when standard output is absolutely necessary or when using it for temporary debugging purposes, do not use System.out.print, System.err.print, or related methods in production-level applications.
- It is difficult to identify where the output originated.
- With a logging API, the source of the output can be identified more easily through log format configuration, and the output destination, log level, and other settings can be changed centrally.
Lambdas
Lambda expressions may be used wherever they are applicable.
Stream API
The Stream API may be used.
However, because an instance is generated for each intermediate operation in the Stream API, performance may be worse than when using an enhanced for loop.
When implementing performance-critical processing, it is recommended to measure the performance of each approach before deciding which implementation method to use.
var (Local-Variable Type Inference)
As a general rule, do not use var.
As can be seen from the widespread adoption of TypeScript and similar technologies, ensuring type safety is strongly emphasized in modern team development. Robustness of the code should be prioritized over the reduced effort provided by type inference.
However, its use is permitted in exceptional cases where not using var would have a significantly greater disadvantage due to factors such as scope.