Commit a837c9

2026-01-16 09:25:51 Melisha Dsouza: added link
CMMI/Guidelines/Coding Standard/Core Java.md ..
@@ 35,8 35,7 @@
* Line length should not exceed 120 characters.
* Opening and closing braces must be formatted using one of the following two methods:
**Method 1:** On a line by themselves at the same level of indentation as the initiating keyword.
- ```
- Java
+ ```Java
if ( byteBuf == null )
{
@@ 44,22 43,22 @@
}
```
**Exception**: the closing brace of the do-while statement.
- ```
- Java
- if ( byteBuf == null ) {
- byteBuf = new ByteBuffer( BUFFER_SIZE );
- }
+ ```Java
+ do
+ {
+ charNumber++;
+ ch = clientName.getChar( charNumber );
+
+ } while ( ch != '\0' );
```
**Method 2:** Opening brace on the same line as the initiating keyword and closing brace on a line by itself at the same level of indentation as the initiating keyword.
- ```
- Java
+ ```Java
if ( byteBuf == null ) {
byteBuf = new ByteBuffer( BUFFER_SIZE );
}
```
**Exception**: the closing brace of the do-while and try statements.
- ```
- Java
+ ```Java
do {
charNumber++;
ch = clientName.getChar( charNumber );
@@ 78,13 77,11 @@
* Always write the left parenthesis directly after a function name (no intervening space).
* Surround operators with spaces.
Don't do things like this:
- ```
- java
+ ```java
newXPos+=recClient.Width()+recUpdate.Width()+margin*columns;
```
It makes the operators easy to miss in a quick inspection. Do this instead:
- ```
- Java
+ ```Java
newXPos += recClient.Width() + recUpdate.Width() + margin * columns;
```
* When a statement spans more than one line, break the statement in a way that each line is obviously syntactically incorrect, and indent the continued line or lines in a way that makes the continuation more visible.
@@ 94,8 91,7 @@
String addressLine1 = getApartmentNumber() + getStreetAddress() + getStreetName();
```
The code below provides a strong visual cue that it's continued on the next line:
- ```
- Java
+ ```Java
String addressLine1 = getApartmentNumber() + getStreetAddress()
+ getStreetName();
```
@@ 103,8 99,8 @@
##### **2.3.1 Rules:**
* All classes and public methods must be preceded by a javadoc comment.
* Class javadoc comments must contain a meaningful description of the class and an @author tag for each person who has worked on any part of the class.
- ```
- Java
+
+ ```Java
/**
* <p>COPYRIGHT</p>
* <p>Blast Radius -- Copyright (C) 2007 Blast Radius
@@ 127,8 123,7 @@
}
```
* Method javadoc comments must include a meaningful description of the method, @param tags for each parameter, and, if applicable, @return and @exception tags.
- ```
- Java
+ ```Java
/**
* Adds a graphic object to the bounding box. If any of the object's
* dimensions fall outside the box, the box's dimensions will grow to
@@ 156,22 151,19 @@
### **2.5 Naming Conventions**
#### **2.5.1 Rules:**
* Whenever mixed-case names are made up of more than one word, the first letter of each word following the first should be uppercase.
- ```
- Java
+ ```Java
closeFile();
Button okButton;
int accountTotal;
int average;
```
* Whenever all-uppercase names are made up of more than one word, each word should be separated with an underscore.
- ```
- java
+ ```java
final int MAX_RANGE = 100;
final String BUTTON_NAME = "a button name";
```
* Methods should be named so that they describe what the method does, starting with an active verb whenever possible.
- ```
- Java
+ ```Java
protected void hideComponent() { /* ... */ }
public int getAverage() { /* ... */ }
public void refreshScreen() { /* ... */ }
@@ 180,16 172,14 @@
* Modifier methods should begin with "set".
* Components should end with the type of the component.
* This is to make the use of the variable a bit more obvious. For example `"ageTextField"` is unambiguous, while "age" may be mistaken for a numeric value.
- ```
- java
+ ```java
Button cancelButton = new Button();
List customerNameList;
BigGrid salesTrackingGrid;
```
* Class names should be a description of the class, and should be mixed case and begin with an uppercase letter.
* Interface names should be a description of the interface's services.
- ```
- Java
+ ```Java
interface Compressable { /* ... */ }
interface Singleton { /* ... */ }
```
@@ 200,8 190,7 @@
##### **2.5.2 Recommendations:**
* Avoid the overuse of "i", "j", and "k" as variable names.
* These variable names don't offer much in the way of providing readability. Compare:
- ```
- Java
+ ```Java
for ( int i = 0; i < totalMonthsDisplayed; i++ )
{
for ( j = 0; j < totalSales; j++ )
@@ 211,8 200,7 @@
}
```
... with ...
- ```
- Java
+ ```Java
for ( int row = 0; row < totalMonthsDisplayed; row++ )
{
for ( column = 0; column < totalSales; column++ )
@@ 228,16 216,14 @@
* Hiding data provides all the benefits of using abstract data types, and limits the places that data can be changed (and/or corrupted). Giving an object the ability to prevent access to its internal state also allows it to test itself whenever its state is queried or changed to ensure that the change is consistent with the object's internal state.
**Don't do this:**
- ```
- Java
+ ```Java
public class Foo
{
public int counter;
}
```
**Do this instead:**
- ```
- Java
+ ```Java
public class Foo
{
private int counter;
@@ 259,8 245,7 @@
#### **2.6.2 Recommendations:**
* When a private data member has a public or protected access method, those methods should be used internally by the class as much as possible to provide consistency.
**For example, given the following class:**
- ```
- Java
+ ```Java
class Dimensions
{
public void setDimensions( int width, int height ) { /* ... */ }
@@ 274,14 259,12 @@
}
```
The code in the body of `Dimension.getArea()` could look like this:
- ```
- Java
+ ```Java
area = width * height;
```
This would work, but will need to be modified if the height or width were changed from a data member to a calculated value. The following code would require no such modification:
- ```
- Java
+ ```Java
area = getWidth() * getHeight();
```
@@ 303,15 286,13 @@
##### **2.8.1 Rules:**
* Avoid the use of numeric values in code, use symbolic values instead.
**For example:**
- ```
- java
+ ```java
colWidth = strWidth + 10 + ( level * 3 );
// ...
cellWidth = cellStrWidth + 10;
```
For the unfortunate programmer who has to maintain (or fix) the above code, there's no indication of what "10" or "3" represents, or whether both "10"s represent the same thing. And if the code maintainer finally figures out that "10" probably represents margin widths, and changes it to something smaller, there's an excellent chance that an instance will be missed, and more time will be wasted tracking down a difficult-to-find bug. Something like the following code should be written in the first place:
- ```
- Java
+ ```Java
final int COL_INDENT_WIDTH = 3; // amount to indent, per level
final int COL_LEFT_MARGIN = 5; // width of column left margin in pixels
final int COL_RIGHT_MARGIN = 5; // width of column right margin in pixels
@@ 326,13 307,11 @@
* Variables are to be declared with the smallest possible scope.
* Each variable is to be declared in a separate declaration statement, and have a commented description.
**Don't do this:**
- ```
- Java
+ ```Java
int moveAmount, selectedIndex;
```
**Do this:**
- ```
- Java
+ ```Java
int moveAmount; // number of items to move
int selectedIndex; // currently selected item
```
@@ 340,8 319,7 @@
###### **2.9.1 Rules:**
* The code which follows a case label must always be terminated by a break statement.
* The switch statement must always contain a default branch, which handles unexpected cases.
- ```
- Java
+ ```Java
switch (tag)
{
case A:
@@ 361,8 339,7 @@
* A switch statement must always contain a default branch which handles unexpected cases.
* All flow control statements (if, else, while, for and do) must have opening and closing braces, even if the block contains no statements.
Empty loops can be deceiving. In the example below, it's easy to mistakenly think that the last line is contained in the loop:
- ```
- Java
+ ```Java
for ( int rowNumber = initialRow;
( rowNumber < totalRows ) && !getRow( rowNumber ).getIsSelected() &&
( getRow( rowNumber ).getNumberOfCells() > 0 );
@@ 370,8 347,7 @@
numberOfRowFound = rowNumber;
```
When the braces are included, the empty loop is unmistakable:
- ```
- Java
+ ```Java
for ( int rowNumber = initialRow;
( rowNumber < totalRows ) && !getRow( rowNumber ).getIsSelected() &&
( getRow( rowNumber ).getNumberOfCells() > 0 );
@@ 383,13 359,11 @@
```
* Use an explicit if...else... structure rather than the ternary statement.
The ternary statement acts as a shortcut for the if...else... statement. However, the statement:
- ```
- java
+ ```java
( rowNumber == 0 ) ? selectTable() : selectRow( rowNumber );
```
...will likely compile the same as the more readable:
- ```
- Java
+ ```Java
if ( rowNumber == 0 )
{
selectTable();
@@ 400,8 374,7 @@
}
```
**Exception**: cases in which a ternary statement simplifies an assignment.
- ```
- Java
+ ```Java
double scale = ( isHalfScale() ? 0.5 : 1 );
// ...may be more readable than...
@@ 426,8 399,7 @@
* **Avoid the use of continue.**
`continue` tends to make loops harder to understand by concealing the structure of program execution. When tempted to use them, try to use an if...else.. statement instead.
Exception: a `continue` statement near the top of a loop can sometimes make the code more readable by avoiding a series of if...else... statements, or a complex loop control structure. For example:
- ```
- Java
+ ```Java
while ( row != null )
{
if ( row.getIsEmpty() )
@@ 441,8 413,7 @@
```
* **Avoid the use of break in anything but the switch statement.**
break tends to make loops harder to understand by concealing their exit conditions. Here's an example of break that confuses the structure of a loop:
- ```
- Java
+ ```Java
while ( true )
{
Rectangle areaRect = area.getRectArea();
@@ 461,8 432,7 @@
```
**Exception**: break can sometimes be used judiciously to avoid messy nested if...else statements in loops or a large number of boolean conditions in the control statement at the top:
- ```
- Java
+ ```Java
while ( ch != '\u0000' )
{
// if this is a metastring token, drop out of the loop
@@ 478,8 448,7 @@
The flow of control within a function is more difficult to understand when there are multiple exit points.
**Exception**: early returns can sometimes be used at the beginning of a function to avoid long if...else.. constructions. When used in this way, it's recommended that they are documented in a way that draws attention to them.
- ```
- Java
+ ```Java
boolean setName( Client client, String name )
{
int clientIndex = findClient( client );
@@ 494,20 463,29 @@
##### **2.10.1 Recommendations:**
* **Comment in a style that's easy to maintain.**
Example of a hard-to-maintain commenting style:
- ```
- Java
+ ```Java
//--------------------------------------//
// get the size of the buffer //
//--------------------------------------//
```
Example of easy-to-maintain commenting styles:
+ ```Java
+ //------------------------------
+ // get the size of the buffer
+ //------------------------------
+
+ /*
+ * get the size of the buffer
+ * then allocate another buffer of the same size.
+ */
+ ```
* **Comment as you go.**
Don't code with the intention of going back later and putting comments in. Try to comment first and code around the comments.
* **Avoid non-data endline comments.**
Endline comments are difficult to maintain because they have to aligned properly, are difficult to edit, and there usually isn't enough space to comment effectively.
+
**Exceptions**: data declarations, and comments at the end of blocks. Example of these:
- ```
- Java
+ ```Java
int numberOfKeys; // number of virtual keystrokes
// ...
} // switch
@@ 515,8 493,7 @@
```
* **Don't duplicate the code in the comment.**
The following comments are redundant:
- ```
- Java
+ ```Java
// if the allocation flag is more than zero
if ( allocSize > 0 )
{
@@ 525,8 502,7 @@
}
```
This comment explains what's actually happening:
- ```
- Java
+ ```Java
// if a buffer was successfully allocated, record the size
if ( allocSize > 0 )
{
@@ 536,8 512,7 @@
#### **2.11 Exception-Handling**
##### **2.11.1 Rules:**
* **Where there is a clear separation between presentation classes and integration classes, the integration class should repackage checked exceptions to pass to the presentation class to preserve encapsulation.**
- ```
- Java
+ ```Java
public class UserDAOImpl implements UserDAO
{
findByUserId(String userId)
@@ 559,8 534,7 @@
* **Preserve the original stack trace information throughout the life of the Exception.**
If an exception is caught in an integration class, and an exception is to be re-thrown to the presentation class, the newly thrown exception must preserve the caught exception stack trace.
* **Exceptions should be logged once whenever they are caught except as outlined by rule 4 and dealt with where they are caught, exceptions should not be passed to generic exception handling methods.**
- ```
- Java
+ ```Java
public class UserDAOImpl implements UserDAO
{
findByUserId(String userId)
@@ 580,8 554,7 @@
}
```
* **Swallowed checked exceptions should be avoided, and where they cannot be avoided proper commenting should document why an empty catch block exists. The general exception java.lang.Exception should never be caught.**
- ```
- Java
+ ```Java
try
{
AdditionalData additionalData = getAdditionalUserData(userId);
@@ 595,8 568,7 @@
}
```
* **A function should not contain split try catch blocks, where multiple checked exceptions are caught they should be handled in subsequent catch blocks or if necessary in nested try blocks.**
- ```
- Java
+ ```Java
try
{
User user = (User)getSqlMapClientTemplate().queryForObject(GET_USER, userId);
@@ 616,8 588,7 @@
* **Catch subclasses before base classes.**
If you catch the base class of an exception before trying to catch classes derived from it, the first catch block will catch all derived exceptions:
- ```
- Java
+ ```Java
try
{
doSomething();
@@ 647,8 618,7 @@
* **Always use try-with-resources for AutoCloseable resources.**
This ensures proper resource cleanup and prevents resource leaks.
- ```
- Java
+ ```Java
// Good
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
return reader.readLine();
@@ 664,8 634,7 @@
```
* **Close resources in the reverse order of their creation in finally blocks (when try-with-resources cannot be used).**
* **Avoid creating unnecessary objects in loops.**
- ```
- Java
+ ```Java
// Bad
for (int i = 0; i < 1000; i++) {
String status = "Processing " + i;
@@ 678,8 647,7 @@
}
```
* **Never ignore InterruptedException without re-interrupting the thread.**
- ```
- Java
+ ```Java
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
@@ 689,8 657,7 @@
```
##### **2.13.2 Recommendations:**
* **Use StringBuilder or StringBuffer for string concatenation in loops.**
- ```
- Java
+ ```Java
// Bad
String result = "";
for (String item : items) {
@@ 707,8 674,7 @@
* **Consider using object pooling only for expensive-to-create objects (e.g., database connections, thread pools).**
* **Avoid using finalizers. Use try-with-resources or explicit cleanup methods instead.**
* **Be aware of autoboxing/unboxing costs in performance-critical code.**
- ```
- Java
+ ```Java
// Bad - autoboxing in loop
Integer sum = 0;
for (int i = 0; i < 1000000; i++) {
@@ 722,8 688,7 @@
}
```
* **Use lazy initialization for expensive objects only when necessary.**
- ```
- Java
+ ```Java
private volatile ExpensiveObject instance;
public ExpensiveObject getInstance() {
@@ 742,8 707,7 @@
* **Always use the highest-level concurrency utilities available** (Executor framework, concurrent collections) rather than wait(), notify(), and synchronized blocks when possible.
* **Document thread-safety guarantees for all classes.**
Use annotations like` @ThreadSafe`, `@NotThreadSafe`, or `@Immutable` in javadoc.
- ```
- Java
+ ```Java
/**
* This class is thread-safe. All methods can be called concurrently.
* @ThreadSafe
@@ 754,16 718,14 @@
```
* **Never expose mutable internal state without proper synchronization.**
* **Always use the volatile keyword for flags that are set by one thread and read by others.**
- ```
- Java
+ ```Java
private volatile boolean shutdownRequested = false;
```
* **Avoid holding locks while calling methods on objects outside your control.**
This can lead to deadlocks.
* **Always acquire multiple locks in a fixed global order to prevent deadlock.**
* **Use thread-safe collections instead of manually synchronizing collection access.**
- ```
- Java
+ ```Java
// Good
Map<String, String> map = new ConcurrentHashMap<>();
@@ 772,8 734,7 @@
```
##### **2.14.2 Recommendations:**
* **Prefer immutable objects for thread safety.**
- ```
- Java
+ ```Java
public final class ImmutablePerson {
private final String name;
private final int age;
@@ 788,8 749,7 @@
}
```
* **Use ExecutorService instead of creating threads directly.**
- ```
- Java
+ ```Java
// Good
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> performTask());
@@ 801,8 761,7 @@
* **Prefer ReentrantLock over synchronized when you need advanced features** (tryLock, timed locks, interruptible locks).
* **Use CountDownLatch, CyclicBarrier, or Phaser for coordinating multiple threads.**
* **Avoid ThreadLocal unless absolutely necessary, and always clean up ThreadLocal variables.**
- ```
- Java
+ ```Java
private static final ThreadLocal<DateFormat> dateFormat =
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
@@ 811,8 770,7 @@
}
```
* **Use CompletableFuture for asynchronous programming.**
- ```
- Java
+ ```Java
CompletableFuture.supplyAsync(() -> fetchData())
.thenApply(data -> processData(data))
.thenAccept(result -> saveResult(result))
@@ 830,16 788,14 @@
* **Prefer interfaces to abstract classes for defining types.**
Interfaces provide more flexibility as Java supports multiple interface implementation but only single inheritance.
* Use functional interfaces for single abstract method interfaces, and annotate with @FunctionalInterface.
- ```
- Java
+ ```Java
@FunctionalInterface
public interface DataProcessor {
void process(Data data);
}
```
* **Never expose collection implementations in public APIs. Return interfaces instead.**
- ```
- Java
+ ```Java
// Good
public List<String> getNames() {
return new ArrayList<>(names);
@@ 851,8 807,7 @@
}
```
* **Return empty collections or arrays instead of null.**
- ```
- Java
+ ```Java
// Good
public List<Customer> getCustomers() {
return customers.isEmpty() ? Collections.emptyList() : new ArrayList<>(customers);
@@ 864,8 819,7 @@
}
```
* **Use defensive copying for mutable objects passed to or returned from methods.**
- ```
- Java
+ ```Java
public class DateRange {
private final Date start;
private final Date end;
@@ 887,8 841,7 @@
* **Keep interfaces small and focused (Interface Segregation Principle).**
* **Use default methods in interfaces sparingly, primarily for evolution.**
- ```
- Java
+ ```Java
public interface Repository {
List<Entity> findAll();
@@ 901,8 854,7 @@
```
* **Prefer method overloading to optional parameters for API design.**
* **Use Builder pattern for classes with many parameters.**
- ```
- Java
+ ```Java
public class User {
private final String name;
private final String email;
@@ 963,8 915,7 @@
* `TreeMap` for sorted maps
* **Specify initial capacity for collections when the size is known in advance.**
- ```
- Java
+ ```Java
// Good
List<String> list = new ArrayList<>(expectedSize);
Map<String, String> map = new HashMap<>(expectedSize);
@@ 973,8 924,7 @@
List<String> list = new ArrayList<>(); // Will resize multiple times
```
* **Never remove elements from a collection while iterating with for-each loop.**
- ```
- Java
+ ```Java
// Bad - ConcurrentModificationException
for (String item : list) {
if (condition) {
@@ 995,8 945,7 @@
list.removeIf(item -> condition);
```
* **Use Collections.unmodifiable or List.of(), Set.of(), Map.of() to return immutable collections.***
- ```
- Java
+ ```Java
// Good (Java 9+)
List<String> immutableList = List.of("a", "b", "c");
Map<String, Integer> immutableMap = Map.of("key1", 1, "key2", 2);
@@ 1018,8 967,7 @@
##### **2.16.2 Recommendations:**
* **Use the diamond operator (<>) to avoid redundant type information.**
- ```
- Java
+ ```Java
// Good
Map<String, List<String>> map = new HashMap<>();
@@ 1036,8 984,7 @@
List<String> list = Arrays.asList("a", "b", "c");
```
* **Use EnumSet instead of bit fields for enum collections.**
- ```
- Java
+ ```Java
// Good
Set<DayOfWeek> weekend = EnumSet.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
@@ 1051,8 998,7 @@
```
* **Consider using Guava collections for advanced use cases (Multimap, BiMap, Table, etc.).**
* **Use Collection.toArray(new T[0]) instead of Collection.toArray(new T[size]).**
- ```
- Java
+ ```Java
// Good
String[] array = list.toArray(new String[0]);
@@ 1074,8 1020,7 @@
#### **2.17 Java 8+ Features Standards**
##### **2.17.1 Rules:**
* **Use lambda expressions instead of anonymous inner classes for functional interfaces.**
- ```
- Java
+ ```Java
// Good
list.forEach(item -> System.out.println(item));
@@ 1088,8 1033,7 @@
});
```
* **Use method references when they are clearer than lambda expressions.**
- ```
- Java
+ ```Java
// Good
list.forEach(System.out::println);
@@ 1097,8 1041,7 @@
list.forEach(item -> System.out.println(item));
```
* **Use Optional to represent potentially absent values, but not for collections, arrays, or method parameters.**
- ```
- Java
+ ```Java
// Good
public Optional<User> findUserById(String id) {
return Optional.ofNullable(userMap.get(id));
@@ 1111,8 1054,7 @@
public Optional<List<User>> getUsers() { }
```
* **Never call Optional.get() without checking Optional.isPresent() first, or use proper Optional methods.**
- ```
- Java
+ ```Java
// Bad
Optional<User> user = findUser();
User u = user.get(); // May throw NoSuchElementException
@@ 1125,8 1067,7 @@
user.ifPresent(u -> processUser(u));
```
* **Use Stream API for collection processing, but avoid overusing streams for simple iterations.**
- ```
- Java
+ ```Java
// Good - streams add value
List<String> names = users.stream()
.filter(user -> user.isActive())
@@ 1142,16 1083,14 @@
}
```
* **Always close streams that are backed by I/O resources.**
- ```
- Java
+ ```Java
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
lines.filter(line -> line.contains("error"))
.forEach(System.out::println);
}
```
* **Use java.time package (LocalDate, LocalDateTime, ZonedDateTime) instead of Date and Calendar.**
- ```
- Java
+ ```Java
// Good
LocalDate today = LocalDate.now();
LocalDateTime now = LocalDateTime.now();
@@ 1165,8 1104,7 @@
##### **2.17.2 Recommendations:**
* **Prefer functional composition over imperative code when it improves readability.**
* **Use Collectors for stream terminal operations.**
- ```
- Java
+ ```Java
// Collect to list
List<String> names = users.stream()
.map(User::getName)
@@ 1185,8 1123,7 @@
.collect(Collectors.groupingBy(Employee::getDepartment));
```
* **Use Optional.orElseThrow() for validation.**
- ```
- Java
+ ```Java
User user = findUserById(id)
.orElseThrow(() -> new UserNotFoundException("User not found: " + id));
```
@@ 1198,16 1135,14 @@
.flatMap(Address::getZipCode);
```
* **Use parallel streams judiciously, only for CPU-intensive operations on large datasets.**
- ```
- Java
+ ```Java
// Use parallel streams only when appropriate
long count = largeList.parallelStream()
.filter(this::expensiveOperation)
.count();
```
* **Use Stream.iterate() or Stream.generate() for infinite streams with limit().**
- ```
- Java
+ ```Java
Stream.iterate(0, n -> n + 1)
.limit(10)
.forEach(System.out::println);
@@ 1216,8 1151,7 @@
* **Leverage default and static methods in interfaces for backward compatibility.**
* **Use @FunctionalInterface annotation for functional interfaces.**
* **Consider using var (Java 10+) for local variables when the type is obvious.**
- ```
- Java
+ ``` Java
// Good - type is obvious
var list = new ArrayList<String>();
var user = userRepository.findById(id);
@@ 1228,8 1162,7 @@
#### **2.18 Logging Standards**
##### **2.18.1 Rules:**
* **Use SLF4J as the logging facade, not Log4j or java.util.logging directly.**
- ```
- Java
+ ```Java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ 1245,8 1178,7 @@
* **DEBUG**: Detailed information for debugging
* **TRACE**: Very detailed information, typically for diagnosis
* **Never log sensitive information (passwords, credit cards, PII, tokens, session IDs)**
- ```
- Java
+ ```Java
// Bad
logger.info("User logged in: {}", user.getPassword());
@@ 1254,8 1186,7 @@
logger.info("User logged in: {}", user.getUsername());
```
* **Use parameterized logging instead of string concatenation.**
- ```
- Java
+ ```Java
// Good
logger.debug("Processing user {} with status {}", userId, status);
@@ 1263,8 1194,7 @@
logger.debug("Processing user " + userId + " with status " + status);
```
* **Always log exceptions with the exception object, not just the message.**
- ```
- Java
+ ```Java
// Good
try {
processData();
@@ 1278,16 1208,14 @@
}
```
* **Guard expensive log statements with level checks.**
- ```
- Java
+ ```Java
if (logger.isDebugEnabled()) {
logger.debug("Complex calculation result: {}", expensiveCalculation());
}
```
##### **2.18.2 Recommendations:**
* **Use MDC (Mapped Diagnostic Context) for request tracking.**
- ```
- Java
+ ```Java
MDC.put("requestId", requestId);
MDC.put("userId", userId);
try {
@@ 1298,8 1226,7 @@
}
```
* **Log method entry and exit only at DEBUG or TRACE level.**
- ```
- Java
+ ```Java
public void processOrder(Order order) {
logger.debug("Entering processOrder with order: {}", order.getId());
try {
@@ 1312,13 1239,12 @@
}
```
* **Use structured logging for complex data.**
- ```
- Java
+ ```Java
logger.info("Order processed: orderId={}, userId={}, amount={}, status={}",
order.getId(), order.getUserId(), order.getAmount(), order.getStatus());
```
* **Avoid logging in loops unless absolutely necessary.**
- ```
+ ```Java
// Bad
for (User user : users) {
logger.debug("Processing user: {}", user.getId());
@@ 1332,7 1258,7 @@
}
```
* **Include context in log messages.**
- ```
+ ```Java
// Bad
logger.error("Processing failed");
@@ 1347,12 1273,12 @@
#### **2.19 Testing and Mocking Standards**
##### **2.19.1 Rules:**
* **Follow naming convention for test classes**: `<ClassUnderTest>Test`
- ```
+ ```Java
// Class under test: UserService.java
// Test class: UserServiceTest.java
```
* **Follow naming convention for test methods:** `testMethodName_StateUnderTest_ExpectedBehavior` or `methodName_StateUnderTest_ExpectedBehavior`
- ```
+ ```Java
@Test
public void findUserById_UserExists_ReturnsUser() { }
@@ 1360,7 1286,7 @@
public void findUserById_UserNotFound_ThrowsException() { }
```
* **Structure tests using the Arrange-Act-Assert (AAA) pattern.**
- ```
+ ```Java
@Test
public void calculateTotal_WithDiscount_ReturnsDiscountedTotal() {
// Arrange
@@ 1377,7 1303,7 @@
```
* **Each test method should test one specific behavior or scenario.**
* **Use @Before/@BeforeEach for common setup and @After/@AfterEach for cleanup.**
- ```
+ ```Java
@BeforeEach
public void setUp() {
userRepository = mock(UserRepository.class);
@@ 1390,7 1316,7 @@
}
```
* **Always use assertion libraries (JUnit assertions, AssertJ, Hamcrest).**
- ```
+ ```Java
// Good - JUnit 5
assertEquals(expected, actual);
assertThrows(IllegalArgumentException.class, () -> service.process(null));
@@ 1401,7 1327,7 @@
.contains("item1", "item2");
```
* **Never catch exceptions in tests; use assertThrows instead.**
- ```
+ ```Java
// Good
assertThrows(UserNotFoundException.class, () -> userService.findById("invalid"));
@@ 1414,7 1340,7 @@
}
```
* **Mock external dependencies, but don't mock the class under test.**
- ```
+ ```Java
@Test
public void createUser_ValidUser_SavesUser() {
// Arrange
@@ 1435,7 1361,7 @@
##### **2.19.2 Recommendations:**
* **Use Mockito for mocking, avoid PowerMock unless absolutely necessary.**
- ```
+ ```Java
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@@ 1453,7 1379,7 @@
}
```
* **Use ArgumentCaptor to verify complex method arguments.**
- ```
+ ```Java
@Test
public void createUser_ValidUser_SavesWithCorrectData() {
ArgumentCaptor<User> userCaptor = ArgumentCaptor.forClass(User.class);
@@ 1467,7 1393,7 @@
}
```
* **Use @ParameterizedTest for testing multiple inputs.**
- ```
+ ```Java
@ParameterizedTest
@ValueSource(strings = {"", " ", " "})
public void isBlank_BlankStrings_ReturnsTrue(String input) {
@@ 1485,7 1411,7 @@
}
```
* **Use test fixtures for complex test data setup.**
- ```
+ ```Java
public class UserFixtures {
public static User createDefaultUser() {
return new User("John", "john@example.com", 30);
@@ 1501,7 1427,7 @@
* **Aim for high test coverage, but focus on critical paths and edge cases.**
* **Use integration tests for testing component interactions, unit tests for isolated logic**.
* **Use @SpringBootTest sparingly; prefer @WebMvcTest, @DataJpaTest, etc., for focused testing.**
- ```
+ ```Java
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
@@ 1521,7 1447,7 @@
}
```
* **Use test containers for integration testing with databases and external services**
- ```
+ ```Java
@Testcontainers
public class UserRepositoryIntegrationTest {
@@ 1537,7 1463,7 @@
* **Never use System.out.println() in tests; use proper assertions and logging.**
* **Keep tests fast. Slow tests won't be run frequently.**
* **Use BDD style for better readability (given-when-then).**
- ```
+ ```Java
@Test
public void userRegistration_ValidData_CreatesUser() {
// Given
@@ 1555,10 1481,12 @@
```
* **Document complex test scenarios with comments.**
* **Use @Disabled with a reason when temporarily disabling tests.**
- ```
+ ```Java
@Test
@Disabled("Disabled until bug #123 is fixed")
public void testComplexScenario() {
// Test code
}
```
+
+ **Document** - [Enovate Coding Standards - Core Java](https://docs.google.com/document/d/1EaOaSk-hbuje0igvIxl1DXcHQROc3KP-S49eD1IUGqg/edit?tab=t.0)
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9