From 48401665ae2e31ad86609fce6ccaa8d37d25f335 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 25 Apr 2025 17:41:45 -0400 Subject: [PATCH] java: update to latest Pull in changes: * Update the Style Guide to talk about text blocks. * Added External TODO style section in Java style guide. * Update camel-case to explain how to separate adjacent numeric words. * Adjust indentation of `// fall through` comments * Remove forward looking promises about the formatter * Updates to account for inline @return Javadoc tag. * Integrate JAKE Java 21 Documentation branch into mainline. * Remove exception from '6.2 Caught exceptions: not ignored' for tests * Add style guidance for `package-info.java` and `module-info.java` files. * Correct possibly confusing indentation of an ellipsis. PiperOrigin-RevId: 751565114 --- javaguide.html | 279 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 203 insertions(+), 76 deletions(-) diff --git a/javaguide.html b/javaguide.html index ac4f707..aba8487 100644 --- a/javaguide.html +++ b/javaguide.html @@ -38,8 +38,8 @@ avoids giving advice that isn't clearly enforceable (whether by human o

In this document, unless otherwise clarified:

    -
  1. The term class is used inclusively to mean an "ordinary" class, enum class, - interface or annotation type (@interface).
  2. +
  3. The term class is used inclusively to mean an "ordinary" class, record class, enum + class, interface or annotation type (@interface).
  4. The term member (of a class) is used inclusively to mean a nested class, field, method, or constructor; that is, all top-level contents of a class except initializers @@ -62,8 +62,8 @@ code. Optional formatting choices made in examples should not be enforced as rul

    2.1 File name

    -

    The source file name consists of the case-sensitive name of the top-level class it contains -(of which there is exactly one), plus the +

    For a source file containing classes, the file name consists of the case-sensitive name of the +top-level class (of which there is exactly one), plus the .java extension.

    2.2 File encoding: UTF-8

    @@ -94,6 +94,7 @@ anywhere in a source file. This implies that:

    \n, \f, \r, +\s, \", \' and \\), that sequence @@ -157,7 +158,7 @@ programs are broken and they must be fixed.

    3 Source file structure
    -

    A source file consists of, in order:

    +

    An ordinary source file consists of, in order:

    1. License or copyright information, if present
    2. @@ -169,6 +170,11 @@ programs are broken and they must be fixed.

      Exactly one blank line separates each section that is present.

      +

      A package-info.java file is the same, but without the top-level class.

      + +

      A module-info.java file does not contain a package statement and replaces the +single top-level class with a module declaration, but otherwise follows the same structure.

      +

      If license or copyright information belongs in a file, it belongs here.

      @@ -245,6 +251,22 @@ members in between. The same applies to multiple constructors (which always have This rule applies even when modifiers such as static or private differ between the methods.

      +

      3.5 Module declaration

      + +

      3.5.1 Ordering and spacing of module directives

      + +

      Module directives are ordered as follows:

      + +
        +
      1. All requires directives in a single block.
      2. +
      3. All exports directives in a single block.
      4. +
      5. All opens directives in a single block.
      6. +
      7. All uses directives in a single block.
      8. +
      9. All provides directives in a single block.
      10. +
      + +

      A single blank line separates each block that is present.

      +

      4 Formatting

      Terminology Note: block-like construct refers to @@ -289,7 +311,7 @@ for nonempty blocks and block-like constructs:

      Exception: In places where these rules allow a single statement ending with a semicolon (;), a block of statements can appear, and the opening brace of this block is preceded by a line break. Blocks like these are typically introduced to -limit the scope of local variables, for example inside switch statements.

      +limit the scope of local variables.

      Examples:

      @@ -384,6 +406,8 @@ you may choose to wrap the line earlier than where this rule strictly requires.< 3.2 Package statement and 3.3 Import statements). +
    3. Contents of text blocks.
    4. +
    5. Command lines in a comment that may be copied-and-pasted into a shell.
    6. Very long identifiers, on the rare occasions they are called for, are allowed to exceed the @@ -442,22 +466,28 @@ without the need to line-wrap.

    7. -
    8. A method or constructor name stays attached to the open parenthesis +
    9. A method, constructor, or record-class name stays attached to the open parenthesis (() that follows it.
    10. A comma (,) stays attached to the token that precedes it.
    11. -
    12. A line is never broken adjacent to the arrow in a lambda, except that a - break may come immediately after the arrow if the body of the lambda consists - of a single unbraced expression. Examples: +
    13. A line is never broken adjacent to the arrow in a lambda or a switch rule, except that a + break may come immediately after the arrow if the text following it consists of a single unbraced + expression. Examples:
      MyLambda<String, Long, Object> lambda =
           (String label, Long value, Object obj) -> {
      -        ...
      +      ...
           };
       
       Predicate<String> predicate = str ->
           longExpressionInvolving(str);
      +
      +switch (x) {
      +  case ColorPoint(Color color, Point(int x, int y)) ->
      +      handleColorPoint(color, x, y);
      +  ...
      +}
       
    @@ -550,7 +580,9 @@ Javadoc, a single ASCII space also appears in the following places only< for ("foreach") statement
  5. the arrow in a lambda expression: - (String str) -> str.length()
  6. + (String str) -> str.length()
    + or switch rule: + case "FOO" -> bar(); but not @@ -693,28 +725,57 @@ new int[] { 3, String[] args, not String args[].

    -

    4.8.4 Switch statements

    +

    4.8.4 Switch statements and expressions

    -

    Terminology Note: Inside the braces of a -switch block are one or more statement groups. Each statement group consists of -one or more switch labels (either case FOO: or -default:), followed by one or more statements (or, for -the last statement group, zero or more statements).

    +

    For historical reasons, the Java language has two distinct syntaxes for switch, which we can call old-style and +new-style. New-style switches use an arrow +(->) after the switch labels, while old-style switches +use a colon (:). + +

    Terminology Note: Inside the braces of a +switch block are either one or more switch rules (new-style); +or one or more statement groups (old-style). A switch +rule consists of a switch label (case ... +or default) followed by -> and an expression, block, or throw. A statement group consists of one or more switch labels each followed by +a colon, then one or more statements, or, for the last statement group, zero or +more statements. (These definitions match the Java Language Specification, +ยง14.11.)

    4.8.4.1 Indentation
    -

    As with any other block, the contents of a switch block are indented +2.

    +

    As with any other block, the contents of a switch block are indented +2. Each switch label +starts with this +2 indentation.

    -

    After a switch label, there is a line break, and the indentation level is increased +2, exactly -as if a block were being opened. The following switch label returns to the previous indentation -level, as if a block had been closed.

    +

    In a new-style switch, a switch rule can be written on a single line if it otherwise follows +Google style. (It must not exceed the column limit, and if it contains a non-empty block then +there must be a line break after {.) The line-wrapping +rules of Section 4.5 apply, including the +4 indent for +continuation lines. For a switch rule with a non-empty block after the arrow, the same rules apply +as for blocks elsewhere: lines between { and +} are indented a further +2 relative to the line with the +switch label. + +

    switch (number) {
    +  case 0, 1 -> handleZeroOrOne();
    +  case 2 ->
    +      handleTwoWithAnExtremelyLongMethodCallThatWouldNotFitOnTheSameLine();
    +  default -> {
    +    logger.atInfo().log("Surprising number %s", number);
    +    handleSurprisingNumber(number);
    +  }
    +}
    +
    + +

    In an old-style switch, the colon of each switch label is followed by a line break. The +statements within a statement group start with a further +2 indentation.

    4.8.4.2 Fall-through: commented
    -

    Within a switch block, each statement group either terminates abruptly (with a +

    Within an old-style switch block, each statement group either terminates abruptly (with a break, continue, return or thrown exception), or is marked with a comment @@ -727,7 +788,7 @@ the last statement group of the switch block. Example:

    case 1: case 2: prepareOneOrTwo(); - // fall through + // fall through case 3: handleOneTwoOrThree(); break; @@ -739,17 +800,28 @@ the last statement group of the switch block. Example:

    Notice that no comment is needed after case 1:, only at the end of the statement group.

    -
    4.8.4.3 Presence of the default label
    +

    There is no fall-through in new-style switches.

    -

    Each switch statement includes a default statement -group, even if it contains no code.

    +
    4.8.4.3 Exhaustiveness and presence of the default label
    -

    Exception: A switch statement for an enum type may omit -the default statement group, if it includes -explicit cases covering all possible values of that type. This enables IDEs or other static -analysis tools to issue a warning if any cases were missed. +

    The Java language requires switch expressions and many kinds of switch statements to be +exhaustive. That effectively means that every possible value that could be switched on will +be matched by one of the switch labels. A switch is exhaustive if it has a default label, but also for example if the value being switched +on is an enum and every value of the enum is matched by a switch label. Google Style requires +every switch to be exhaustive, even those where the language itself does not require it. +This may require adding a default label, even if it +contains no code.

    -

    +
    4.8.4.4 Switch expressions
    + +

    Switch expressions must be new-style switches:

    + +
      return switch (list.size()) {
    +    case 0 -> "";
    +    case 1 -> list.getFirst();
    +    default -> String.join(", ", list);
    +  };
    +

    4.8.5 Annotations

    @@ -765,18 +837,29 @@ annotation if it is meta-annotated with public @Nullable Person getPersonByName(String name); -
    4.8.5.2 Class annotations
    +
    4.8.5.2 Class, package, and module annotations
    -

    Annotations applying to a class appear immediately after the +

    Annotations applying to a class, package, or module declaration appear immediately after the documentation block, and each annotation is listed on a line of its own (that is, one annotation per line). These line breaks do not constitute line-wrapping (Section 4.5, Line-wrapping), so the indentation level is not -increased. Example:

    +increased. Examples:

    -
    @Deprecated
    +
    /** This is a class. */
    +@Deprecated
     @CheckReturnValue
     public final class Frozzler { ... }
     
    +
    /** This is a package. */
    +@Deprecated
    +@CheckReturnValue
    +package com.example.frozzler;
    +
    +
    /** This is a module. */
    +@Deprecated
    +@SuppressWarnings("CheckReturnValue")
    +module com.example.frozzler { ... }
    +
    4.8.5.3 Method and constructor annotations
    @@ -839,8 +922,36 @@ Such a comment renders the line non-blank.

    re-wrap the lines when necessary (paragraph-style). Most formatters don't re-wrap lines in // ... style comment blocks.

    + +
    4.8.6.2 TODO comments
    + +
    +

    Use TODO comments for code that is temporary, a short-term solution, or good-enough + but not perfect.

    + +

    A TODO comment begins with the word TODO in all caps, a following + colon, and a link to a resource that contains the context, ideally a bug reference. A bug + reference is preferable because bugs are tracked and have follow-up comments. Follow this piece of + context with an explanatory string introduced with a hyphen -.

    + +

    The purpose is to have a consistent TODO format that can be searched to find out how + to get more details.

    + +
    // TODO: crbug.com/12345678 - Remove this after the 2047q4 compatibility window expires.
    +
    + +

    Avoid adding TODOs that refer to an individual or team as the context:

    + +
    // TODO: @yourusername - File an issue and use a '*' for repetition.
    +
    + +

    If your TODO is of the form "At a future date do something" make sure that you + either include a very specific date ("Fix by November 2005") or a very specific event ("Remove + this code when all clients can handle XML responses.").

    +
    +

    4.8.7 Modifiers

    @@ -848,17 +959,35 @@ re-wrap the lines when necessary (paragraph-style). Most formatters don't re-wra recommended by the Java Language Specification:

    -
    public protected private abstract default static final transient volatile synchronized native strictfp
    +
    public protected private abstract default static final sealed non-sealed
    +  transient volatile synchronized native strictfp
     
    +

    Modifiers on requires module directives, when present, appear in the following +order:

    + +
    transitive static
    +

    4.8.8 Numeric Literals

    long-valued integer literals use an uppercase L suffix, never lowercase (to avoid confusion with the digit 1). For example, 3000000000L rather than 3000000000l.

    +

    4.8.9 Text Blocks

    + +

    The opening """ of a text block is always on a new line. That line may + either follow the same indentation rules as other constructs, or it may have no indentation at all + (so it starts at the left margin). The closing """ is on a new line + with the same indentation as the opening """, and may be followed on the + same line by further code. Each line of text in the text block is indented at least as much as the + opening and closing """. (If a line is indented further, then the string + literal defined by the text block will have space at the start of that line.) + +

    The contents of a text block may exceed the column limit. + -

    5 Naming

    +

    5 Naming

    5.1 Rules common to all identifiers

    @@ -874,10 +1003,10 @@ names are not Google Style: name_, 5.2 Rules by identifier type -

    5.2.1 Package names

    +

    5.2.1 Package and module names

    -

    Package names use only lowercase letters and digits (no underscores). Consecutive words are -simply concatenated together. For example, com.example.deepspace, not +

    Package and module names use only lowercase letters and digits (no underscores). Consecutive +words are simply concatenated together. For example, com.example.deepspace, not com.example.deepSpace or com.example.deep_space.

    @@ -1017,10 +1146,15 @@ predictability, Google Style specifies the following (nearly) deterministic sche -
  7. Finally, join all the words into a single identifier.
  8. +
  9. Finally, join all the words into a single identifier. Note that the casing of the original + words is almost entirely disregarded.
-

Note that the casing of the original words is almost entirely disregarded. Examples:

+

In very rare circumstances (for example, multipart version numbers), you may need to use +underscores to separate adjacent numbers, since numbers do not have upper and lower case variants. +

+ +

Examples:

@@ -1059,6 +1193,11 @@ predictability, Google Style specifies the following (nearly) deterministic sche + + + + +
turnOn2sv turnOn2Sv
"Guava 33.4.6"guava33_4_6guava3346

*Acceptable, but not recommended.

@@ -1075,8 +1214,8 @@ language: for example "nonempty" and "non-empty" are both correct, so the method

A method is marked with the @Override annotation whenever it is legal. This includes a class method overriding a superclass method, a class method -implementing an interface method, and an interface method respecifying a superinterface -method.

+implementing an interface method, an interface method respecifying a superinterface method, and an +explicitly declared accessor method for a record component.

Exception: @Override may be omitted when the parent method is @@ -1085,7 +1224,7 @@ method.

6.2 Caught exceptions: not ignored

-

Except as noted below, it is very rarely correct to do nothing in response to a caught +

It is very rarely correct to do nothing in response to a caught exception. (Typical responses are to log it, or if it is considered "impossible", rethrow it as an AssertionError.)

@@ -1101,18 +1240,6 @@ justified is explained in a comment.

return handleTextResponse(response); -

Exception: In tests, a caught exception may be ignored -without comment if its name is or begins with expected. The -following is a very common idiom for ensuring that the code under test does throw an -exception of the expected type, so a comment is unnecessary here.

- -
try {
-  emptyStack.pop();
-  fail();
-} catch (NoSuchElementException expected) {
-}
-
-

6.3 Static members: qualified using class

When a reference to a static class member must be qualified, it is qualified with that class's @@ -1156,7 +1283,7 @@ public int method(String p1) { ... }

The basic form is always acceptable. The single-line form may be substituted when the entirety of the Javadoc block (including comment markers) can fit on a single line. Note that this only -applies when there are no block tags such as @return.

+applies when there are no block tags such as @param.

7.1.2 Paragraphs

@@ -1191,32 +1318,32 @@ punctuated as if it were a complete sentence.

Tip: A common mistake is to write simple Javadoc in the form /** @return the customer ID */. This is incorrect, and should be changed to -/** Returns the customer ID. */.

+/** Returns the customer ID. */ or +/** {@return the customer ID} */.

7.3 Where Javadoc is used

-

At the minimum, Javadoc is present for every -public class, and every -public or -protected member of such a class, with a few exceptions -noted below.

+

At the minimum, Javadoc is present for every visible class, member, or record +component, with a few exceptions noted below. A top-level class is visible if it is public; a member is visible if it is public or protected and its containing +class is visible; and a record component is visible if its containing record is visible. -

Additional Javadoc content may also be present, as explained in Section 7.3.4, +

Additional Javadoc content may also be present, as explained in Section 7.3.4, Non-required Javadoc.

7.3.1 Exception: self-explanatory members

-

Javadoc is optional for "simple, obvious" members like -getFoo(), in cases where there really and truly - is nothing else worthwhile to say but "Returns the foo".

+

Javadoc is optional for "simple, obvious" members and record components, such as a +getFoo() method, if there really and +truly is nothing else worthwhile to say but "the foo".

Important: it is not appropriate to cite this exception to justify -omitting relevant information that a typical reader might need to know. For example, for a method -named getCanonicalName, don't omit its documentation -(with the rationale that it would say only -/** Returns the canonical name. */) if a typical reader may have no idea -what the term "canonical name" means!

+omitting relevant information that a typical reader might need to know. For example, for a record +component named canonicalName, don't omit its +documentation (with the rationale that it would say only +@param canonicalName the canonical name) if a typical reader may have +no idea what the term "canonical name" means!

7.3.2 Exception: overrides

@@ -1228,7 +1355,7 @@ what the term "canonical name" means!

7.3.4 Non-required Javadoc

-

Other classes and members have Javadoc as needed or desired. +

Other classes, members, and record components have Javadoc as needed or desired.

Whenever an implementation comment would be used to define the overall purpose or behavior of a class or member, that comment is written as Javadoc instead (using /**).

@@ -1241,4 +1368,4 @@ class or member, that comment is written as Javadoc instead (using /** - \ No newline at end of file +