diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java
index 82aff06b9f4..466cf3cac9a 100644
--- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java
+++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java
@@ -55,6 +55,13 @@
*
* public void foo(final char @NotNull [] param) {} // No violation
*
+ *
+ * Note: This check processes the
+ *
+ * LITERAL_SYNCHRONIZED token only when it appears as a part of a
+ *
+ * synchronized statement, i.e. {@code synchronized(this) {}}.
+ *
*
* -
* Property {@code allowLineBreaks} - Control whether whitespace is allowed
@@ -284,7 +291,10 @@ private static DetailAST getWhitespaceFollowedNode(DetailAST ast) {
*/
private static boolean shouldCheckWhitespaceAfter(DetailAST ast) {
final DetailAST previousSibling = ast.getPreviousSibling();
- return previousSibling == null || previousSibling.getType() != TokenTypes.ANNOTATIONS;
+ final boolean isSynchronizedMethod = ast.getType() == TokenTypes.LITERAL_SYNCHRONIZED
+ && ast.getFirstChild() == null;
+ return !isSynchronizedMethod
+ && (previousSibling == null || previousSibling.getType() != TokenTypes.ANNOTATIONS);
}
/**
diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/meta/checks/whitespace/NoWhitespaceAfterCheck.xml b/src/main/resources/com/puppycrawl/tools/checkstyle/meta/checks/whitespace/NoWhitespaceAfterCheck.xml
index bfd69888671..cc6e14f0d6d 100644
--- a/src/main/resources/com/puppycrawl/tools/checkstyle/meta/checks/whitespace/NoWhitespaceAfterCheck.xml
+++ b/src/main/resources/com/puppycrawl/tools/checkstyle/meta/checks/whitespace/NoWhitespaceAfterCheck.xml
@@ -30,7 +30,14 @@
</p>
<pre>
public void foo(final char @NotNull [] param) {} // No violation
- </pre>
+ </pre>
+ <p>
+ Note: This check processes the
+ <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LITERAL_SYNCHRONIZED">
+ LITERAL_SYNCHRONIZED</a> token only when it appears as a part of a
+ <a href="https://docs.oracle.com/javase/specs/jls/se19/html/jls-14.html#jls-14.19">
+ synchronized statement</a>, i.e. {@code synchronized(this) {}}.
+ </p>
Control whether whitespace is allowed
diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheckTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheckTest.java
index 262664fff98..f5d8feb8783 100644
--- a/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheckTest.java
+++ b/src/test/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheckTest.java
@@ -354,6 +354,17 @@ public void testNoWhitespaceAfterWithEmoji() throws Exception {
getPath("InputNoWhitespaceAfterWithEmoji.java"), expected);
}
+ @Test
+ public void testNoWhitespaceAfterSynchronized() throws Exception {
+ final String[] expected = {
+ "18:9: " + getCheckMessage(MSG_KEY, "synchronized"),
+ };
+
+ verifyWithInlineConfigParser(
+ getPath("InputNoWhitespaceAfterSynchronized.java"),
+ expected);
+ }
+
/**
* Creates MOCK lexical token and returns AST node for this token.
*
diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter/InputNoWhitespaceAfterSynchronized.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter/InputNoWhitespaceAfterSynchronized.java
new file mode 100644
index 00000000000..74bc3446132
--- /dev/null
+++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter/InputNoWhitespaceAfterSynchronized.java
@@ -0,0 +1,59 @@
+/*
+NoWhitespaceAfter
+allowLineBreaks = (default)true
+tokens = LITERAL_SYNCHRONIZED
+
+
+*/
+package com.puppycrawl.tools.checkstyle.checks.whitespace.nowhitespaceafter;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+public class InputNoWhitespaceAfterSynchronized {
+
+ private final Object lock = new Object();
+
+ void m1() {
+ synchronized (lock) {} // violation
+ synchronized(lock) {} // ok
+ }
+
+ synchronized int m2() { // ok
+ return 2;
+ }
+
+ synchronized private int[] m3() { // ok
+ return new int[]{2};
+ }
+
+ synchronized int[] m4() { // ok
+ return new int[]{2};
+ }
+
+ private final synchronized int m5() { // ok
+ return 2;
+ }
+
+ synchronized T m6() { // ok
+ return null;
+ }
+
+ @SyncAnno synchronized T m7() { // ok
+ return null;
+ }
+
+ @SyncAnno private synchronized T m8() { // ok
+ return null;
+ }
+
+ // Note that we do not check 'synchronized' as a modifier,
+ // convention is to have type parameters of a generic method
+ // be surrounded by whitespace.
+ synchronized void m9() {} // ok
+ synchronized void m10() {} // ok
+}
+
+@Target(ElementType.METHOD)
+@interface SyncAnno {
+}
diff --git a/src/xdocs/config_whitespace.xml b/src/xdocs/config_whitespace.xml
index 55e3ac40676..fddb40226b0 100644
--- a/src/xdocs/config_whitespace.xml
+++ b/src/xdocs/config_whitespace.xml
@@ -1353,6 +1353,13 @@ import static java.math.BigInteger.ZERO;
+
+ Note: This check processes the
+
+ LITERAL_SYNCHRONIZED token only when it appears as a part of a
+
+ synchronized statement, i.e. synchronized(this) {}
.
+