Skip to main content

Overview

Following consistent coding standards makes the OpenJDK codebase easier to read, maintain, and contribute to. This guide covers the coding conventions for HotSpot (C++) and general Java development.
This guide is based on the official HotSpot Coding Style document, which is the authoritative source for HotSpot development.

Why Follow Style Guidelines?

Consistent code style provides several benefits:
  • Readability: Code is easier to understand when it follows familiar patterns
  • Maintainability: Consistent style reduces cognitive load when reviewing or modifying code
  • Collaboration: A unified style makes it easier for multiple developers to work together
  • Quality: Style guidelines often encode best practices that prevent bugs

HotSpot C++ Style Guide

Naming Conventions

Use mixed-case with capitalized first letter (FooBar):
class ThreadLocalStorage { ... };
class GarbageCollector { ... };
typedef int32_t jint;
  • Class names should be noun phrases
  • Use “er” suffix for classes representing actions
  • Abbreviations are usually fully capitalized (e.g., HTML not Html)
Use lowercase with underscores (foo_bar):
void process_request();
int max_value = 100;
const char* file_name;
  • Function names should be verb phrases
  • Boolean functions can start with is_ or has_
  • Keep names descriptive but concise
Prefix with underscore, use lowercase with underscores (_foo_bar):
class MyClass {
  int _counter;
  bool _is_initialized;
  void* _data_ptr;
};
  • Leading underscore distinguishes members from local variables
  • Use public accessor functions for external access
May be upper-case or mixed-case depending on context:
const int MaxThreads = 256;
#define PRODUCT_ONLY(code) code
static const size_t DEFAULT_SIZE = 1024;
  • Follow existing patterns in the code area
  • Ensure constants are visually distinct from variables

Code Structure

File Organization

// Include guards
#ifndef SHARE_VM_RUNTIME_THREAD_HPP
#define SHARE_VM_RUNTIME_THREAD_HPP

// HotSpot includes (alphabetically sorted)
#include "memory/allocation.hpp"
#include "runtime/handles.hpp"
#include "utilities/globalDefinitions.hpp"

// System includes (separate section)
#include <vector>

class Thread : public ThreadShadow {
  // Class definition
};

#endif // SHARE_VM_RUNTIME_THREAD_HPP
  • All source files must have globally unique basenames
  • Keep include lines alphabetically sorted
  • Separate HotSpot and system includes with a blank line

Class Design

1

Keep Functions Small

Functions should fit on one screen (roughly 50-80 lines):
// Good: Small, focused function
void Thread::initialize() {
  set_state(INITIALIZED);
  create_stack();
  setup_thread_local_storage();
}

// If larger, split into helper functions
void Thread::complex_operation() {
  prepare_operation();
  execute_operation();
  finalize_operation();
}
2

Use Meaningful Names

Avoid categorical nouns and generic verbs:
// Bad
void compute(int param) { ... }
int value;

// Good
void calculate_hash_code(int seed) { ... }
int hash_code;
3

Document Invariants

Use assertions to document and verify class invariants:
void Thread::set_priority(ThreadPriority priority) {
  assert(priority >= MinPriority && priority <= MaxPriority,
         "priority out of range");
  _priority = priority;
}

Formatting and Whitespace

Indentation and Braces

Use One-True-Brace-Style (1TBS):
// Opening brace on same line
if (condition) {
  do_something();
} else {
  do_something_else();
}

// Functions: brace can be on same or next line
void function() {
  // implementation
}

// Or for emphasis:
void important_function()
{
  // implementation
}

// Always use braces, even for single statements
if (test) {
  single_statement();
}

// Exception: very simple one-liners can omit braces
if (ptr == nullptr) return;
  • Indentation: 2 spaces (no tabs)
  • No tabs: Set your editor to use spaces
  • Always use braces for substatements (with rare exceptions)

Spacing

// Spaces around operators
int result = a + b * c;
if (x == y) { ... }

// Space after control flow keywords
while (condition) { ... }
for (int i = 0; i < n; i++) { ... }
if (test) { ... }

// No space around control expressions
while (test) { ... }     // Correct
while ( test ) { ... }   // Wrong

// Parentheses for clarity
if ((a & b) != 0) { ... }
int x = (a << 2) | (b & 0xFF);

C++ Feature Usage

Permitted Features

// Use auto for clarity, not just convenience
auto it = map.find(key);  // Clear: iterator type obvious
auto lock = MutexLocker(mutex);  // Clear: RAII pattern

// Avoid when type is important to readability
int count = get_count();  // Better than: auto count = get_count();

Forbidden Features

The following C++ features must not be used in HotSpot code:
  • Exceptions: Build configuration disables exceptions
  • RTTI: dynamic_cast and typeid are disabled
  • Standard Library (mostly): Use HotSpot utilities instead
  • Global operator new/delete: Use HotSpot memory allocation
  • Multiple inheritance: Single inheritance only
  • Namespaces: Use “all static” classes instead

Memory Management

HotSpot uses custom memory allocation:
// Use HotSpot allocation, not global new/delete
Thread* thread = new Thread();  // Wrong!

// Use ResourceMark for arena allocation
ResourceMark rm;
char* buffer = NEW_RESOURCE_ARRAY(char, size);

// C-heap allocation with NMT support
char* data = NEW_C_HEAP_ARRAY(char, size, mtInternal);
FREE_C_HEAP_ARRAY(char, data);

// RAII for automatic cleanup
ResourceMark rm;
// Allocations automatically freed when rm goes out of scope

Error Handling

// Use assert for preconditions and invariants
assert(ptr != nullptr, "pointer must not be null");
assert(index >= 0 && index < length, "index out of bounds");

// Use guarantee for critical checks
guarantee(heap != nullptr, "heap initialization failed");

// Use ShouldNotReachHere for impossible cases
switch (type) {
  case TypeA: handle_a(); break;
  case TypeB: handle_b(); break;
  default: ShouldNotReachHere();
}

// Use HotSpot exception mechanism (not C++ exceptions)
THREAD;
Handle h = ...;
if (HAS_PENDING_EXCEPTION) {
  // Handle error
  return;
}

Java Code Style

General Conventions

For Java code in the JDK libraries:
// Class names: PascalCase
public class ArrayList { ... }
public interface Comparable { ... }

// Method and variable names: camelCase
public void calculateHashCode() { ... }
private int maxSize;

// Constants: UPPER_SNAKE_CASE
public static final int MAX_VALUE = Integer.MAX_VALUE;
public static final String DEFAULT_ENCODING = "UTF-8";

// Package names: lowercase
package java.util.concurrent;
package javax.swing;

Documentation

/**
 * Returns a hash code value for this object.
 * <p>
 * The general contract of {@code hashCode} is:
 * <ul>
 * <li>Consistency: multiple invocations return the same value
 * <li>Equality: equal objects must have equal hash codes
 * </ul>
 *
 * @return a hash code value for this object
 * @see #equals(Object)
 */
@Override
public int hashCode() {
    return Objects.hash(field1, field2);
}
  • Document all public APIs
  • Include @param, @return, @throws as appropriate
  • Use {@code} for code fragments
  • Reference related methods with @see
  • Explain contracts and invariants

Testing Standards

Test Naming

// JTReg test structure
/*
 * @test
 * @bug 8123456
 * @summary Test String.hashCode with null checks
 * @run main StringHashCodeTest
 */
public class StringHashCodeTest {
    public static void main(String[] args) {
        testNormalCase();
        testEdgeCases();
    }
}

Test Organization

Tests should be:
  • Organized by component in test/jdk, test/hotspot/jtreg, etc.
  • Tagged with @bug for issue tracking
  • Self-contained and reproducible
  • Fast enough for regular testing

Editor Configuration

VS Code Settings

{
  "editor.insertSpaces": true,
  "editor.tabSize": 2,
  "editor.detectIndentation": false,
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true
}

Vim Settings

set expandtab
set tabstop=2
set shiftwidth=2
set softtabstop=2

Emacs Settings

(setq-default indent-tabs-mode nil)
(setq c-basic-offset 2)
(setq tab-width 2)

Style Checking

Running Style Checks

The JDK includes tools to check code style:
# Check modified files
make jcheck

# The build system also performs some style validation
make images

Best Practices Summary

1

Follow Existing Patterns

When modifying existing code, match the surrounding style even if it differs from these guidelines.
2

Prioritize Readability

Code is read far more often than written. Make it easy to understand.
3

Use Meaningful Names

Names should clearly convey purpose. Avoid abbreviations unless well-known.
4

Keep It Simple

Favor simple, straightforward solutions over clever optimizations.
5

Document Non-Obvious Code

Add comments for complex algorithms or subtle invariants.

Resources

When in doubt, look at existing code in the same area and follow those patterns. Consistency within a component is more important than strict adherence to any single style guide.

Build docs developers (and LLMs) love