xcuti/java icon
public
Published on 5/9/2025
Java

Rules

Java Coding Rules for AI-Generated Code

Current Date: May 9, 2025

Build System: Gradle with Kotlin DSL must be used as the main build and compilation system.

1. File Structure and Organization

1.1. File Naming: * Extension: .java. * Name: Must match the public class/interface name, case-sensitive.

1.2. File Encoding: * UTF-8 for all Java source files.

1.3. File Organization: * One top-level public class or interface per .java file. * Multiple top-level classes/interfaces in one file discouraged (except private helpers or very closely related small classes); only one can be public.

1.4. Package and Imports: 1.4.1. Package Declaration: * Mandatory for every source file (unless default package, which is strongly discouraged). * First statement in the file. 1.4.2. Import Statements: * Follow package declaration, precede class/interface definitions. * Order: 1. static ... (grouped) 2. java.* 3. javax.* 4. Other external libraries (e.g., org.*, com.*) 5. Internal project imports * Alphabetical within each group. * Avoid wildcard imports (e.g., java.util.*), prefer specific imports. Exception: enum members or utility class static members if numerous are used. * Do not import from java.lang (e.g., String, Integer). * Remove all unused imports.

2. Naming Conventions

2.1. General Principles: * Names: Descriptive, self-explanatory. English. * Abbreviations: Avoid unless widely understood (e.g., URL, HTML, AI).

2.2. Packages: * lowercase.only.concatenated. * Reversed domain name: com.example.project.module. * No underscores or hyphens. * Example: com.yourdomain.ai.featureengineering

2.3. Classes and Interfaces: * UpperCamelCase (PascalCase). * Nouns or noun phrases. Examples: NeuralNetworkClassifier, DataProcessor, PredictionResult. * Interfaces: May be adjectives (e.g., Runnable) or noun-based like classes. I prefix (e.g., IDataService) permissible if project convention improves clarity. * Abstract Classes: Describe the abstraction (e.g., Shape). Avoid Abstract prefix unless dictated by established patterns. * Test Classes: Suffix with Test (e.g., MyServiceTest).

2.4. Methods: * lowerCamelCase. * Verbs or verb phrases. Examples: trainModel(), predict(features), calculateLoss(). * Getters: getX(). For booleans: isX() or hasX(). * Setters: setX(value). * Boolean-returning methods: Sound like questions (e.g., isEmpty()).

2.5. Variables: 2.5.1. Instance and Static Variables: * lowerCamelCase. Examples: customerName, totalConnections. * No m or s prefixes unless strong project convention. 2.5.2. Local Variables: * lowerCamelCase. Examples: index, userName. * Declare close to first use. 2.5.3. Parameters: * lowerCamelCase. Examples: message, count. * Avoid single-letter names except for trivial cases (loop counters i,j,k, coordinates x,y,z, short lambdas).

2.6. Constants (static final fields): * UPPER_SNAKE_CASE. Examples: MAX_CONNECTIONS, DEFAULT_TIMEOUT. * Declared static final. * For mutable objects, ensure true constancy or provide an unmodifiable view.

2.7. Enums: * Type: UpperCamelCase. * Constants: UPPER_SNAKE_CASE.

2.8. Type Parameters (Generics): * Single uppercase letter (e.g., T, E, K, V). * Descriptive UpperCamelCase if it significantly improves readability for complex generics (e.g., RequestT, InputType).

3. Code Formatting

3.1. Indentation: * 4 spaces. No tabs.

3.2. Line Length: * Maximum 100-120 characters. Wrap lines exceeding this.

3.3. Wrapping Lines: * Continuation line indent: Typically 8 spaces (two levels) or aligned with a higher-level expression. * Break before an operator. * Prefer higher-level breaks.

3.4. Braces: * K&R style ("Egyptian brackets"): * Opening brace {: End of the line starting the construct. * Closing brace }: Own line, aligned with the start of the construct. * Always use braces for if, else, for, do, while blocks. java // Example public class MyClass { public void myMethod(int arg) { if (arg > 0) { // code } else { // code } } }

3.5. Blank Lines (Vertical Whitespace): * One blank line: * Between methods. * Between local variables and first statement in a method. * Before block/single-line comments. * Between logical sections within a method. * Between field declarations. * Avoid multiple consecutive blank lines.

3.6. Horizontal Whitespace: * Use a single space: * Around binary operators (+, =, &&). * After commas in argument lists. * After semicolons in for statements. * After colons in enhanced for loops and ternary expressions. * After keywords (if, for, while, switch, try, catch, finally, synchronized) followed by (. * Around -> in lambdas. * No spaces: * Around unary operators (++x, !condition). * Before semicolon or comma. * Between method name and its opening parenthesis (. * After opening parenthesis ( or before closing parenthesis ). * Around dot . operator. * For type casts: after ) of cast and expression (e.g., (String)object).

3.7. Parentheses: * Use liberally for clarity in complex expressions.

3.8. Annotations: * On separate lines preceding the annotated element (unless very short in a parameter list). * @Override first, if present.

4. Documentation and Comments

4.1. Javadoc Comments (/** ... */): * Mandatory for all public classes, interfaces, methods, and non-trivial public/protected fields. * First sentence: Concise summary, ending with a period. * Tags: Use @param, @return, @throws, @see, @since, @deprecated, @author, @version appropriately. * @param <T> Description for generic type parameters. * @throws: Document all checked exceptions and notable runtime exceptions.

4.2. Implementation Comments: 4.2.1. Block Comments (/* ... */): For multi-line explanations of complex logic within methods. 4.2.2. Single-Line Comments (//): For short explanations or end-of-line comments. * Explain why, not just what (if code is self-explanatory). * Avoid redundant comments. * Keep comments updated. * // TODO: Description for pending tasks. * // FIXME: Description for known issues.

4.3. Class/Interface Comments: * Javadoc: Describe purpose, responsibility, basic usage. * Include @author, @version if project policy dictates. * @since for new public APIs.

5. Declarations and Initialization

5.1. Variable Declarations: * One variable per line. * Initialize locals where declared or as soon as value is known. * Declare in narrowest possible scope. * Use final for variables not reassigned (locals, parameters, fields).

5.2. Array Declarations: * int[] array (not int array[]).

5.3. Modifiers Order (common practice): * public/protected/private * abstract * static * final * transient * volatile * default (interface methods) * synchronized * native * strictfp * Example: public static final String MY_CONSTANT = "...";

5.4. Primitive Types vs. Boxed Types: * Prefer primitives (int, boolean) unless nullable type or generic argument is required.

5.5. Using var (Java 10+): * Use for local variables if it enhances readability (reduces boilerplate) and inferred type is clear. * Do not use if it reduces clarity.

6. Statements

6.1. Simplicity: * Write simple, clear statements. Avoid overly complex statements.

6.2. for Loops: * Prefer enhanced for loops (for-each) for collections/arrays if index is not needed. * for (Element element : elements)

6.3. switch Statements: * Always include default case (even if just a comment or throws exception). * Each case usually ends with break. Intentional fall-through must be commented (// fallthrough). * Use new switch expressions (Java 14+) where appropriate.

6.4. try-catch-finally Blocks: * Use try-with-resources for AutoCloseable resources. * Catch specific exceptions, not generic Exception or Throwable (unless necessary and handled properly). * Do not ignore/swallow exceptions (empty catch block) without explicit, commented intent. Log or rethrow. * finally for cleanup code that must always execute.

6.5. return Statements: * Avoid complex expressions if they hinder readability; assign to a well-named local variable first. * Multiple returns acceptable if they improve clarity and reduce nesting.

7. Expressions

7.1. Magic Numbers/Strings: * Avoid. Use named constants.

7.2. String Concatenation: * + operator for simple cases. * StringBuilder, String.format(), or String.join() for complex/loop-based concatenations.

7.3. Ternary Operator (? :): * Use for simple conditional assignments. Avoid nesting.

7.4. Floating-Point Comparisons: * Do not use == or !=. Use a tolerance (epsilon) comparison.

7.5. Null Checks: * Be mindful of NullPointerExceptions. * Use Objects.requireNonNull() or explicit checks for critical parameters/variables. * "constant".equals(variable) to avoid NPE if variable is null. * Utilize Optional (Java 8+) for methods that might not return a value.

8. Concurrency

8.1. Thread Safety: * Ensure classes are thread-safe if intended for multi-threaded access. * Prefer immutable objects (inherently thread-safe). * Use appropriate synchronization ( synchronized keyword, ReentrantLock, java.util.concurrent collections) for shared mutable state. * Minimize scope of synchronized blocks. Avoid excessive synchronization.

8.2. Use java.util.concurrent: * Favor high-level utilities (ExecutorService, ThreadPoolExecutor, Future, CompletableFuture, concurrent collections) over low-level Thread.start(), wait()/notify().

8.3. volatile: * For variables accessed by multiple threads where visibility is critical and complex atomicity is not needed.

9. Performance Considerations

9.1. Premature Optimization: * Avoid. Write clear, correct code first. Profile and optimize bottlenecks if necessary.

9.2. Efficient Data Structures: * Choose appropriate Java Collections based on use case (e.g., ArrayList, LinkedList, HashMap).

9.3. String Manipulation: * Use StringBuilder for building strings in loops or complex scenarios due to string immutability.

9.4. I/O Operations: * Use buffered I/O (e.g., BufferedReader, BufferedInputStream). * Close resources promptly using try-with-resources. * Handle large datasets by streaming or chunking.

9.5. Lazy Initialization: * Use for expensive resources only when necessary; ensure thread-safety if applicable.

9.6. Algorithm Complexity: * Be aware of time and space complexity. Profile to identify bottlenecks.

9.7. Memory Management: * Avoid unnecessary object creation, especially in tight loops. * Be mindful of potential memory leaks.

10. Error Handling and Logging

10.1. Exceptions: * Throw specific, appropriate exceptions. Create custom exceptions for application-specific errors. * Do not use exceptions for normal control flow. * Document thrown exceptions (@throws in Javadoc). * Wrap third-party exceptions in custom exceptions if beneficial for abstraction. * Include context in exception messages.

10.2. Logging: * Use a standard logging framework (SLF4J with Logback or Log4j2). Avoid System.out/err.println(). * Log at appropriate levels (DEBUG, INFO, WARN, ERROR). * Provide meaningful log messages with context. * Avoid logging sensitive information unless properly secured. * Guard verbose logging (DEBUG, TRACE) with if (logger.isDebugEnabled()) if message construction is expensive.

11. Immutability

11.1. Favor Immutability: * Strive for immutable classes: final fields, no setters, defensive copies of mutable fields, prevent extension (final class or private constructors). * Immutable objects are simpler, thread-safe, and freely sharable.

11.2. Collections: * Use Collections.unmodifiable...() or Java 9+ List.of(), Set.of(), Map.of() for unmodifiable/immutable collections.

12. API Design

12.1. Clarity and Usability: * Design APIs easy to understand, use correctly, and hard to use incorrectly.

12.2. Encapsulation: * Hide internal details. Expose only what is necessary.

12.3. Consistency: * Maintain consistency in naming, parameter order, and behavior.

12.4. Use Interfaces: * Program to interfaces, not concrete implementations.

12.5. Avoid null Returns: * Prefer empty collections or Optional for methods that might not find a result.

12.6. Validation: * Validate input parameters for public APIs. Throw IllegalArgumentException, NullPointerException for invalid inputs.

13. Java Features Usage

13.1. Lambdas and Streams (Java 8+): * Use for functional interfaces and declarative collection processing. * Prioritize readability; refactor overly complex lambdas/streams.

13.2. Optional (Java 8+): * Use to represent potentially absent return values. * Avoid as field types or method parameters without strong justification. * Prefer orElse(), orElseGet(), orElseThrow() over isPresent() + get().

13.3. Records (Java 14+): * Use for simple immutable data carrier classes.

13.4. Pattern Matching for instanceof (Java 16+): * Use to reduce boilerplate and improve type safety.

13.5. Sealed Classes (Java 17+): * Use to control inheritance hierarchies.

14. Testing

14.1. Unit Tests: * Mandatory for critical components and business logic. Aim for high coverage. * Frameworks: JUnit, TestNG. * Small, fast, independent tests. Arrange-Act-Assert (AAA) pattern. * Test edge cases, boundary conditions, null inputs, expected failures.

14.2. Integration Tests: * Verify interactions between different components/modules, databases, or external APIs. * Crucial for AI pipelines.

14.3. Model Evaluation Tests (AI-Specific): * Evaluate model performance metrics (accuracy, precision, recall, F1, RMSE, etc.) on validation/test datasets. * Include tests for known inputs/outputs to catch regressions. * Consider tests for fairness, bias, and robustness.

14.4. Testability: * Design code to be testable (e.g., use dependency injection, avoid hard-to-mock static calls for business logic).

14.5. Test Naming: * Clearly indicate what is being tested (e.g., testCalculateScore_emptyInput_throwsException()).

15. Security Best Practices

15.1. Input Validation: * Validate and sanitize all external inputs to prevent injection attacks.

15.2. Dependency Management: * Keep dependencies updated. Scan for known vulnerabilities (e.g., OWASP Dependency-Check).

15.3. Sensitive Data: * No hardcoded secrets (passwords, API keys). Use secure configuration or environment variables. * Handle sensitive data with care (logging, transmission).

15.4. Serialization/Deserialization: * Be cautious with Java serialization. Consider alternatives (JSON, Protobuf). If used, implement readObject carefully, use whitelists.

15.5. Principle of Least Privilege: * Application should run with minimum necessary permissions.

16. AI-Specific Considerations

16.1. Data Handling for AI Models: * Efficient and correct handling of large datasets for preprocessing/feature engineering. * Mind memory usage and processing time for data transformations. * Prefer immutable objects for data points/features. * Encapsulate data cleaning, transformation, normalization logic. Ensure reproducibility. * Validate data quality, consistency, and expected formats early.

16.2. Model Representation: * Clearly define classes for model parameters, configurations, learned weights. * Consider dedicated numerical computation libraries (e.g., DL4J's ND4J, Tribuo) for efficiency.

16.3. Model Serialization/Deserialization (AI Models): * Robust mechanisms for saving/loading trained models (Java serialization, JSON, PMML, ONNX, framework-specific secure formats). * Ensure version compatibility if model formats evolve.

16.4. Algorithmic Clarity: * Strive for clarity reflecting underlying mathematical/logical steps. * Comment complex algorithmic parts, assumptions, trade-offs. * Where possible, leverage well-tested AI/ML library implementations (Deeplearning4j, Weka, Tribuo, Spark MLlib).

16.5. Resource Management for Training/Inference: * Proper management of resources (GPU memory - if applicable, large native memory buffers).

16.6. Reproducibility (AI/ML): * Ensure reproducibility: version code, data, control random seeds, deterministic operations where possible.

16.7. API Design for AI Services: * Clear, well-documented, versioned API endpoints if exposing models. * Consider asynchronous processing for long-running inference. * Define clear request/response schemas.

16.8. Modularity and Reusability (AI Components): * Design data loaders, preprocessors, models, evaluators as independent modules with well-defined interfaces.

16.9. Configuration Management (AI): * Externalize hyperparameters, model configurations, pipeline settings (e.g., properties, YAML, JSON).

17. Code Review and Evolution

17.1. Self-Correction/Refinement: * AI model should aim to review generated code against these rules and refine it.

17.2. Adaptability: * These rules may evolve; AI should be designed to adapt to updated standards.

18. Core Software Engineering Principles

18.1. DRY (Don't Repeat Yourself): * Avoid duplicate code. Encapsulate common logic.

18.2. KISS (Keep It Simple, Stupid): * Prefer simpler, clear solutions over overly complex ones.

18.3. YAGNI (You Aren't Gonna Need It): * Do not implement features not currently required.

18.4. SOLID Principles: * Single Responsibility Principle: A class has one reason to change. * Open/Closed Principle: Open for extension, closed for modification. * Liskov Substitution Principle: Subtypes substitutable for their base types. * Interface Segregation Principle: Clients not forced to depend on interfaces they don't use. * Dependency Inversion Principle: Depend on abstractions, not concretions.

18.5. Composition over Inheritance: * Favor composition for flexibility and to avoid tight coupling.