1. Introduction
Comments are useful when they explain something that the code itself cannot clearly communicate.
In production Java applications, comments should not describe obvious syntax. Their purpose is to capture information such as:
- Why a non-obvious implementation was chosen
- Why a business rule exists
- Why seemingly unnecessary code cannot be removed
- Why a workaround exists
- What external-system limitation influenced the implementation
- Why a particular concurrency, performance, or transactional decision was made
A good comment provides context that would otherwise be lost when the original developer leaves the project.
A bad comment creates noise, duplicates the code, becomes outdated, or gives a false impression about what the application actually does.
During Pull Request review, reviewers should therefore evaluate comments with the same care as executable code.
2. What This Topic Means
Writing useful comments means documenting information that cannot be expressed clearly through Java code, naming, structure, tests, or API design.
For example, this comment provides little value:
// Check if order status is completed
if (order.getStatus() == OrderStatus.COMPLETED) {
sendInvoice(order);
}The code already explains what is happening.
A more useful comment might explain why a particular condition exists:
// Legacy billing API rejects invoices during settlement reconciliation between 01:00 and 01:15 UTC.
if (settlementWindowService.isReconciliationRunning()) {
scheduleInvoiceForRetry(order);
return;
}The second comment captures external operational knowledge that cannot be understood simply by reading the Java statement.
Useful comments generally explain why, while clean code should explain what and how.
3. Why It Matters in Real Projects
Readability
Useful comments help developers understand unusual business rules without reverse-engineering requirements, tickets, or production history.
Maintainability
A future developer can modify code safely when the reason behind an implementation is documented.
Debugging
Comments explaining external dependencies, legacy behavior, retry rules, or known edge conditions can significantly reduce investigation time.
Reliability
Some apparently unnecessary conditions exist to prevent known production failures. Explaining them reduces the chance that someone removes them during refactoring.
Team Development
Large projects often contain code written by developers who are no longer on the team. Comments preserve important technical and business context.
Comments become harmful, however, when they are outdated. An incorrect comment may be more dangerous than having no comment at all.
4. Core Concept
The main principle is:
Code should explain what it does. Comments should explain why something non-obvious is necessary.
Before adding a comment, ask whether the code can be made clearer instead.
Instead of:
// Get active customers
List<Customer> list = repository.findByActiveTrue();Use a meaningful name:
List<Customer> activeCustomers = customerRepository.findByActiveTrue();No comment is required.
Comments become valuable when the reason cannot reasonably be encoded into a class name, method name, variable name, test, or type.
For example:
// Do not replace this with LocalDate.now().
// Billing dates must always be calculated using the tenant's configured timezone.
LocalDate billingDate = LocalDate.now(tenantZoneId);This protects an important domain requirement.
5. Important Rules
- Prefer self-explanatory code over explanatory comments.
- Explain why the implementation exists, not what individual Java statements do.
- Document non-obvious business rules.
- Document external-system constraints when they affect implementation.
- Explain temporary workarounds and reference the reason for them.
- Keep comments close to the code they describe.
- Update comments whenever the related implementation changes.
- Delete comments that are no longer accurate.
- Avoid commented-out production code.
- Never place passwords, API keys, tokens, customer data, or other sensitive information inside comments.
- Avoid writing comments that merely translate Java syntax into English.
- Explain unexpected performance optimizations when the simpler implementation would otherwise appear preferable.
- Explain concurrency assumptions where incorrect modification could create race conditions.
- Use Javadoc primarily for API contracts and externally useful documentation rather than narrating implementation details.
- Treat TODO comments as temporary engineering work, not permanent documentation.
6. Bad Code Example
Consider an order-processing service.
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentClient paymentClient;
public OrderService(OrderRepository orderRepository, PaymentClient paymentClient) {
this.orderRepository = orderRepository;
this.paymentClient = paymentClient;
}
public void processOrder(Long id) {
// Get order
Order o = orderRepository.findById(id).orElseThrow();
// Check status
if (o.getStatus() == OrderStatus.CANCELLED) {
return;
}
// Call payment
PaymentResponse response = paymentClient.charge(o.getPaymentId());
// Check payment
if (response.isSuccessful()) {
// Change status
o.setStatus(OrderStatus.CONFIRMED);
// Save order
orderRepository.save(o);
}
// TODO fix later
// orderRepository.flush();
}
}The code contains many comments, but almost none provide useful information.
7. Problems in the Bad Code
Comments Repeat the Code
Comments such as:
// Get order
// Check status
// Save ordersimply describe the Java statement immediately below them.
They increase visual noise without adding knowledge.
Poor Naming Hidden Behind Comments
The variable:
Order ois unclear.
Instead of compensating with comments, the developer should use:
Order orderUnclear Business Reason
The code silently ignores cancelled orders:
if (o.getStatus() == OrderStatus.CANCELLED) {
return;
}A reviewer may reasonably ask why cancelled orders are silently ignored instead of throwing an exception or returning a result.
If this behavior represents a business rule, the reason should be clear.
Weak TODO Comment
// TODO fix laterThis provides no useful information.
It does not explain:
- What is broken
- Why it cannot be fixed now
- What ticket tracks the work
- Whether production behavior is affected
Commented-Out Code
// orderRepository.flush();Commented-out code should normally be deleted.
Git already stores code history.
Missing Payment-Failure Behavior
The method does nothing when payment fails.
This is primarily a code-design issue rather than a comment issue, but comments should never be used to hide incomplete business behavior.
8. Code Review Findings
A senior reviewer should notice:
- Most comments merely repeat Java statements.
- Variable naming should be improved instead of explained through comments.
- The cancelled-order behavior is not obvious from the method contract.
- The payment failure path is unclear.
- The TODO does not contain actionable information.
- Commented-out repository code should be removed.
- The implementation lacks documentation for any genuinely unusual business behavior.
- The comments will require maintenance despite providing almost no value.
A reviewer should not request more comments everywhere.
The correct review direction is usually:
Improve the code first, then keep only comments that explain important context.
9. Reviewer Comment Example
A professional PR review comment could be:
These comments mostly repeat what the statements already express. Could we remove them and use clearer naming instead? Please keep comments only where we need to explain non-obvious business behavior, such as why cancelled orders are intentionally ignored.
Another useful comment:
Can we remove the commented-out
flush()call? Git history already preserves previous implementations, and leaving dead code here may confuse future maintainers.
For the TODO:
Please either link this TODO to a tracked issue and explain the required follow-up, or remove it if no action is currently planned.
10. Improved Code
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final PaymentClient paymentClient;
public OrderService(OrderRepository orderRepository, PaymentClient paymentClient) {
this.orderRepository = orderRepository;
this.paymentClient = paymentClient;
}
public void processOrder(Long orderId) {
Order order = orderRepository.findById(orderId)
.orElseThrow(() -> new OrderNotFoundException(orderId));
if (order.getStatus() == OrderStatus.CANCELLED) {
return;
}
PaymentResponse paymentResponse = paymentClient.charge(order.getPaymentId());
if (!paymentResponse.isSuccessful()) {
throw new PaymentFailedException(orderId, paymentResponse.getFailureReason());
}
order.setStatus(OrderStatus.CONFIRMED);
orderRepository.save(order);
}
}Most comments disappeared because the code now communicates its intent directly.
Suppose the cancelled-order behavior exists because of a specific external requirement. Then a comment may be justified:
// Cancellation events may be delivered more than once by the legacy order gateway.
// Returning here keeps processing idempotent for already-cancelled orders.
if (order.getStatus() == OrderStatus.CANCELLED) {
return;
}That comment provides information the condition itself cannot communicate.
11. Improved Code Explanation
Meaningful Names
id became:
orderIdo became:
orderresponse became:
paymentResponseThese names eliminate the need for explanatory comments.
Explicit Failure Handling
Payment failure now produces a meaningful exception.
The behavior is visible directly from the code.
Removed Redundant Comments
Statements such as:
orderRepository.save(order);do not need:
// Save orderRemoved Dead Code
The commented-out flush() call was removed.
Previous versions remain available through source control.
Useful Comments Remain Possible
A comment should remain only when additional business or operational context cannot reasonably be expressed through the implementation itself.
12. Bad Code vs Improved Code
| Area | Bad Code | Improved Code |
|---|---|---|
| Readability | Comments compensate for weak naming | Code explains normal behavior itself |
| Maintainability | Many comments must be synchronized | Fewer comments reduce maintenance |
| Testability | Failure behavior is unclear | Payment failure behavior is explicit |
| Reliability | Hidden business assumptions | Important behavior can be documented clearly |
| Reviewability | Reviewer must separate noise from useful information | Important decisions are easier to identify |
The improved solution does not attempt to eliminate comments completely.
It eliminates unnecessary comments.
13. Real Project Scenario
Consider a banking application integrating with an old core-banking platform.
A developer encounters this code:
if (transaction.getAmount().compareTo(BigDecimal.ZERO) == 0) {
return;
}Without context, the developer may think zero-value transactions should still be sent to the downstream service for audit purposes.
However, the existing implementation may intentionally skip them because the external system rejects zero-value transactions.
A useful comment could be:
// CoreBank v4 rejects zero-value settlement transactions with error CB-2041.
// Keep them internal rather than sending them to the settlement endpoint.
if (transaction.getAmount().compareTo(BigDecimal.ZERO) == 0) {
return;
}Months later, another developer sees the condition during refactoring.
Instead of removing it as "unnecessary," the developer immediately understands the production dependency.
That is the type of knowledge comments should preserve.
14. Production Impact
Poor comments can create several production risks.
Incorrect Refactoring
A developer may remove an unusual condition because its purpose is not documented.
Misleading Debugging
An outdated comment may say one thing while the actual code does something different.
Developers may investigate the wrong behavior during an incident.
Maintenance Problems
Hundreds of redundant comments make important documentation difficult to notice.
Regression Bugs
Workarounds for external services, data migrations, legacy schemas, or race conditions may be removed because nobody knows why they exist.
Security Exposure
Sensitive information accidentally stored in comments may appear in:
- Git history
- GitHub
- GitLab
- Bitbucket
- Azure DevOps
- Code-review tools
- CI logs
- Source packages
Comments are part of the source code and should never be treated as a secure storage location.
15. Common Developer Mistakes
Describing Every Statement
Bad:
// Increment retry count
retryCount++;Using Comments Instead of Good Names
Bad:
int x = 5; // Maximum retriesBetter:
int maxRetries = 5;Leaving Commented-Out Code
Bad:
// paymentService.refund(payment);
// auditService.recordRefund(payment);Remove dead code unless there is an exceptional and explicitly documented reason to retain it temporarily.
Writing Vague TODOs
Bad:
// TODO handle thisBetter:
// TODO PAY-1842: Remove fallback after Payment Gateway v2 migration is complete.Even better, where project policy permits, track the issue externally and avoid a permanent TODO.
Allowing Comments to Become Incorrect
Bad:
// Retry payment three times
for (int attempt = 0; attempt < 5; attempt++) {
processPayment();
}The comment now contradicts the code.
Writing Large Historical Essays
Comments should not become a complete history of every previous implementation.
Source control and issue tracking systems are better places for detailed history.
Adding Developer Names
Avoid:
// Added by Rahul on 12/01/2025Git already records authorship.
Explaining Bad Code Instead of Refactoring It
A complicated method should not receive twenty comments if it can instead be divided into well-named methods.
16. Edge Cases
For comments themselves, traditional runtime edge cases such as null or empty strings are not directly relevant.
However, reviewers should consider several maintenance edge cases.
Business Rule Changes
If a business rule changes, does the related comment still describe the current requirement?
External API Upgrades
A workaround comment may no longer be valid after the dependency is upgraded.
Temporary Migration Logic
Temporary comments should make it possible to determine when the temporary logic can be removed.
Concurrency Assumptions
If thread-safety depends on a specific execution model, document the assumption carefully.
Example:
// This cache is modified only by the single-threaded reconciliation executor.
pendingReconciliations.put(transactionId, reconciliation);Such a comment becomes especially important if future developers may change the execution model.
Boundary Behavior
When an unusual boundary exists because of business policy, explain the reason rather than restating the comparison.
17. Performance Considerations
Comments themselves usually have no runtime performance cost because Java comments are not executed by the JVM.
Therefore, performance should not be invented as a concern for ordinary comments.
However, comments can be valuable when explaining non-obvious performance-sensitive code.
For example:
// Fetch IDs first to avoid loading full Order entities for approximately 2M archived records.
List<Long> orderIds = orderRepository.findArchivedOrderIds(cutoffDate);Without the comment, a developer might replace the optimization with a simpler entity query and unintentionally increase memory consumption.
Another example:
// Keep batch size below 500 because the downstream API begins throttling larger requests.
List<List<Customer>> batches = partition(customers, 500);The comment explains why the apparently arbitrary value matters.
Important principle:
Do not comment that code is "faster." Explain the actual constraint or measured reason whenever it matters.
18. Security Considerations
Comments can create serious security problems when developers include sensitive information.
Never write comments such as:
// Production DB password: admin123
// Temporary API key: abc123
// JWT secret used by mobile serviceAlso avoid exposing sensitive customer information:
// Issue occurs for customer John Smith account 8472991Use secure incident-management or ticketing systems instead.
Comments can appropriately explain security decisions.
For example:
// Do not accept tenantId from the request body.
// Authorization is based exclusively on the tenant resolved from the authenticated principal.
String tenantId = authenticatedUser.getTenantId();This comment explains an important security boundary.
Another example:
// Constant-time comparison is intentional to avoid timing leakage for API signatures.
return MessageDigest.isEqual(expectedSignature, suppliedSignature);Security comments are particularly valuable when a future "simplification" could introduce a vulnerability.
19. Testing Considerations
Comments do not normally require automated tests.
Instead, tests should verify the behavior that important comments describe.
Suppose the comment says:
// Duplicate webhook events are ignored to keep payment processing idempotent.There should be a test verifying that behavior.
Example test scenarios:
Positive Case
A new payment webhook is processed successfully.
Duplicate Case
The same webhook ID is submitted twice and the payment is not processed twice.
Failure Case
A malformed webhook produces the expected error behavior.
Integration Test
Verify idempotency against the persistence layer when duplicate requests arrive.
A comment must never replace a test.
Bad approach:
// This method works when customer is null.Better approach:
Write a test proving the expected null behavior.
Comments describe intent.
Tests verify behavior.
20. Refactoring Guidelines
When refactoring comments in an existing project:
- Read the associated code carefully.
- Determine whether the comment explains what the code does or why it exists.
- Replace unclear names before adding more documentation.
- Remove comments that merely duplicate statements.
- Verify business-rule comments against current requirements.
- Check issue trackers before removing workaround comments.
- Search Git history if the reason behind unusual logic is unclear.
- Preserve comments that describe critical external constraints.
- Update comments whenever implementation behavior changes.
- Run existing tests to ensure code refactoring has not changed behavior.
Do not mechanically delete every comment.
Some comments may contain critical production knowledge.
Refactoring should distinguish:
- Noise
- Obsolete documentation
- Important engineering context
21. Best Practices
Let Names Explain Normal Behavior
Prefer:
Customer customer = customerRepository.findById(customerId)
.orElseThrow(() -> new CustomerNotFoundException(customerId));instead of:
// Find customer
Customer c = customerRepository.findById(customerId).orElseThrow();Explain Business Reasons
Good:
// Premium customers retain reservation priority for 15 minutes after payment timeout.
reservation.extendPriorityWindow(Duration.ofMinutes(15));Explain External Constraints
Good:
// Vendor API accepts a maximum of 100 IDs per request.
for (List<Long> batch : partition(productIds, 100)) {
inventoryClient.fetchAvailability(batch);
}Explain Counter-Intuitive Code
Good comments are especially valuable where developers may otherwise "simplify" code incorrectly.
Keep Comments Local
Place the comment near the relevant logic.
Keep Comments Current
Updating behavior without updating documentation should be considered an incomplete change.
Reference Trackable Work
For temporary technical debt:
// TODO ORDER-428: Remove compatibility mapping after all clients migrate to API v3.Use Javadoc for Contracts
Javadoc is useful for:
- Public APIs
- Reusable libraries
- Non-obvious parameters
- Return-value contracts
- Exception behavior
- Important preconditions
Avoid Javadoc that merely repeats method names.
22. Practices to Avoid
Obvious Comments
Avoid:
// Return result
return result;They create noise.
Commented-Out Code
Avoid:
// customer.setActive(false);Use version control.
Change Logs Inside Source Files
Avoid:
// 2024-03-01 Rahul changed timeout
// 2024-05-08 Amit changed timeout again
// 2025-01-10 Sneha fixed timeoutGit already maintains change history.
Vague Warnings
Avoid:
// Important!
// Don't change this!Explain why.
Better:
// Settlement file names are consumed by the partner's fixed-width parser.
// Changing this format requires coordinating a partner-side deployment.Misleading Comments
A wrong comment is worse than no comment because developers may trust it.
Excessive Javadoc
Avoid:
/**
* Gets customer ID.
* @return customer ID
*/
public Long getCustomerId() {
return customerId;
}This provides almost no value.
Sensitive Information
Never store:
- Passwords
- Access tokens
- Private keys
- Customer identifiers
- Security bypass instructions
- Production credentials
inside source comments.
23. Code Review Checklist
During Pull Request review, ask:
- Does this comment provide information that the code itself cannot communicate?
- Is the comment explaining why rather than merely describing what?
- Could clearer naming remove the need for this comment?
- Could a smaller method remove the need for this explanation?
- Is the documented business rule still valid?
- Does the comment accurately match the current implementation?
- Is an external-service limitation documented where necessary?
- Is a non-obvious performance decision explained?
- Is a concurrency assumption documented where modification could be dangerous?
- Are temporary workarounds linked to actionable cleanup work?
- Are there vague TODO comments?
- Is commented-out code being committed?
- Does any comment contain sensitive information?
- Does Javadoc describe a useful API contract rather than repeat the method name?
- Would a future developer understand why this unusual code must remain?
- Should the behavior described by the comment also have an automated test?
24. Common Pull Request Review Comments
- *This comment repeats the method call below it. Can we remove it and let the code remain self-explanatory?*
- *Could we rename this variable instead of using a comment to explain what it contains?*
- *Why is this retry limit fixed at 3? If this comes from a vendor constraint or production finding, please document that reason.*
- *Please remove the commented-out implementation. Git history already preserves the previous version.*
- *This TODO is difficult to act on. Can we reference the tracking ticket and describe the condition under which this workaround can be removed?*
- *The comment says five retries, but the loop currently performs three. Please update either the implementation or the comment so they remain consistent.*
- *This condition is not obvious from the business flow. A short comment explaining why duplicate callbacks are intentionally ignored would help future reviewers.*
- *Please avoid including the real customer/account details in this comment. Use the incident ticket for sensitive production examples.*
- *The Javadoc currently repeats the method signature. Could we document the non-obvious error behavior or remove the Javadoc?*
- *This optimization makes the code less obvious. Please add a short explanation of the database/performance constraint that requires it.*
25. Code Review Exercise
Review the following Spring Boot service.
Identify:
- Problems
- Code smells
- Risks
- Unnecessary comments
- Missing useful comments
- Possible improvements
Do not assume every comment should remain.
@Service
public class NotificationService {
private final NotificationRepository notificationRepository;
private final SmsClient smsClient;
public NotificationService(NotificationRepository notificationRepository, SmsClient smsClient) {
this.notificationRepository = notificationRepository;
this.smsClient = smsClient;
}
public void send(Long id) {
// Get notification
Notification n = notificationRepository.findById(id).orElseThrow();
// Check if processed
if (n.isProcessed()) {
return;
}
// Phone number
String p = n.getPhoneNumber();
// Send SMS
smsClient.send(p, n.getMessage());
// Set processed true
n.setProcessed(true);
// Save
notificationRepository.save(n);
// TODO fix duplicate issue later
// notificationRepository.flush();
// Production API token used during testing was abc-test-123
}
}26. Exercise Solution
The implementation contains several important code-review issues.
Issue 1: Redundant Comments
These comments add no value:
// Get notification
// Check if processed
// Phone number
// Send SMS
// Set processed true
// SaveThey simply translate Java statements into English.
Issue 2: Poor Variable Names
n and p should become:
notification
phoneNumberClear names eliminate several comments automatically.
Issue 3: Weak Exception Handling
This:
orElseThrow()produces a generic NoSuchElementException.
A domain-specific exception provides more useful behavior.
Issue 4: Duplicate Processing Risk
The TODO says:
// TODO fix duplicate issue laterbut gives no explanation.
More importantly, duplicate notification delivery is a real production issue.
Two concurrent requests could both execute:
if (notification.isProcessed())before either transaction updates the row.
Both may send the SMS.
The code therefore requires an actual concurrency/idempotency solution rather than a TODO comment.
Issue 5: Commented-Out Code
// notificationRepository.flush();should be removed.
Issue 6: Sensitive Information
This is unacceptable:
// Production API token used during testing was abc-test-123Secrets must never be stored in source comments.
If a real credential had been committed, simply deleting the comment would not be enough because it may remain in Git history.
The credential should be revoked or rotated according to the organization's security process.
Improved Code
One possible approach is to use a database-backed state transition that prevents multiple workers from claiming the same notification.
@Service
public class NotificationService {
private final NotificationRepository notificationRepository;
private final SmsClient smsClient;
public NotificationService(NotificationRepository notificationRepository, SmsClient smsClient) {
this.notificationRepository = notificationRepository;
this.smsClient = smsClient;
}
@Transactional
public void send(Long notificationId) {
Notification notification = notificationRepository.findByIdForUpdate(notificationId)
.orElseThrow(() -> new NotificationNotFoundException(notificationId));
if (notification.isProcessed()) {
return;
}
smsClient.send(notification.getPhoneNumber(), notification.getMessage());
notification.markProcessed();
}
}Repository example:
public interface NotificationRepository extends JpaRepository<Notification, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select n from Notification n where n.id = :notificationId")
Optional<Notification> findByIdForUpdate(@Param("notificationId") Long notificationId);
}Why the Changes Help
Better Naming
The code now communicates the meaning of each value without comments.
Domain-Specific Exception
Missing notifications produce meaningful application behavior.
Duplicate Protection
The database lock reduces the possibility that two application threads process the same notification simultaneously.
Whether pessimistic locking is the correct strategy depends on the application's traffic, database characteristics, and delivery architecture.
Other production designs may use:
- Atomic status transitions
- Optimistic locking
- Idempotency keys
- Message broker deduplication
- Outbox processing
- Distributed coordination
The important code-review point is that a comment saying "fix duplicate issue later" does not solve concurrency.
Removed Dead Code
The commented flush() statement was deleted.
Removed Credential
Sensitive data is not stored in the repository.
Where a Useful Comment Might Be Appropriate
Suppose the SMS provider guarantees only one accepted message for a particular provider idempotency key.
A comment explaining that integration constraint may be appropriate near the idempotency implementation.
The comment should describe the provider contract, not ordinary Java statements.
27. Interview Perspective
Comment-related questions often appear indirectly in senior Java and code-review interviews.
An interviewer may provide code containing dozens of comments and ask:
- Is this clean code?
- Which comments should remain?
- Which comments indicate weak naming?
- When would you add a comment during code review?
- Would you allow TODO comments?
- Why is commented-out code problematic?
- When should a workaround be documented?
- How do you prevent comments from becoming outdated?
- What should Javadoc contain?
- How would you review comments containing security-sensitive information?
For experienced developers, interviewers usually care less about the statement:
"Comments are good."
They want to hear that comments have a specific purpose.
A strong response is:
Prefer expressive code for normal behavior. Use comments to preserve important context, constraints, decisions, and reasons that cannot be expressed clearly by the code itself.
28. Interview Questions and Answers
Basic Question
Question: When should you write a comment in Java code?
Answer:
Write a comment when important information cannot be communicated clearly through code structure, naming, types, tests, or API design.
Typical examples include:
- Non-obvious business rules
- External API limitations
- Compatibility workarounds
- Concurrency assumptions
- Security decisions
- Performance constraints
- Temporary migration behavior
Do not comment obvious statements.
Intermediate Question
Question: Why are comments that explain what code does usually considered weak?
Answer:
Well-written code should normally communicate what it does through:
- Class names
- Method names
- Variable names
- Types
- Method extraction
- Clear control flow
A comment such as:
// Save customer
customerRepository.save(customer);duplicates information and increases maintenance effort.
If the implementation changes and the comment does not, the comment may become misleading.
Advanced Question
Question: Can comments reduce maintainability?
Answer:
Yes.
Comments create additional information that developers must keep synchronized with executable code.
Problems include:
- Outdated comments
- Incorrect comments
- Duplicated information
- Excessive visual noise
- Dead commented-out code
- Historical notes that belong in Git
- Important documentation being hidden among low-value comments
The goal is not maximum comments. It is maximum clarity with minimum unnecessary documentation.
Scenario-Based Question
Question: You see this code during review:
// Do not change this timeout.
Duration timeout = Duration.ofSeconds(17);What would you do?
Answer:
I would ask why 17 seconds is required.
The current comment warns against modification but does not provide enough context.
If the timeout comes from an external dependency, the code could be improved to something like:
// Vendor closes idle settlement connections after 20 seconds.
// Use 17 seconds to fail locally before the vendor terminates the socket.
Duration settlementTimeout = Duration.ofSeconds(17);A configuration property may also be more appropriate depending on the application.
Code-Review Question
Question: A Pull Request contains large blocks of commented-out Java code. Would you approve it?
Answer:
Normally no.
The developer should remove dead code because:
- Git retains history
- Commented code creates noise
- Developers cannot know whether it is intentionally preserved
- The code may become incompatible with the surrounding implementation
- Static analysis and tests do not verify commented code
I would request removal unless there is a very unusual and clearly justified temporary reason.
Real-Project Question
Question: Give an example where a comment is important in a Spring Boot application.
Answer:
Suppose an application deliberately avoids retrying HTTP 409 responses because a payment provider treats that status as successful duplicate detection.
The implementation may contain:
// Provider returns HTTP 409 when the idempotency key was already processed.
// Do not retry because retrying creates unnecessary duplicate requests.
if (response.statusCode() == HttpStatus.CONFLICT) {
return PaymentResult.ALREADY_PROCESSED;
}Without the comment, someone might treat 409 as a generic failure and add automatic retries.
The comment protects an important integration rule.
29. Quick Rule to Remember
If the code explains what, use the comment to explain why. If the comment only repeats the code, remove it.
30. Final Takeaway
Useful comments are not about adding more text to Java files.
They are about preserving information that developers genuinely need to understand the system.
What the Developer Should Remember
Write clean code first.
Use:
- Meaningful names
- Small focused methods
- Clear domain models
- Explicit error handling
- Good tests
Then add comments only where meaningful context is still missing.
What the Reviewer Should Check
During Pull Request review, verify that:
- Comments add information rather than repeat statements.
- Important business reasons are documented.
- External-system limitations are understandable.
- Temporary workarounds are trackable.
- Comments match current implementation behavior.
- Commented-out code is removed.
- Sensitive information is never included.
- Non-obvious production decisions are preserved for future maintainers.
What Should Be Avoided in Production Code
Avoid:
- Obvious comments
- Misleading comments
- Outdated comments
- Commented-out code
- Vague TODOs
- Developer change logs
- Sensitive information
- Comments compensating for poor naming
- Large explanations that could be replaced with cleaner design
The best production Java code does not need a comment beside every statement.
It uses comments selectively, where the reason behind the code is more important than the syntax visible on the screen.