Skip to main content Link Search Menu Expand Document (external link)

FormatStringConcatenation

WARNING

Simplification

View source code on GitHub

Summary

Defer string concatenation to the invoked method

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("FormatStringConcatenation") to the enclosing element.

Disable this pattern completely by adding -Xep:FormatStringConcatenation:OFF as compiler argument. Learn more.

Samples

Replacement

Shows the difference in example code before and after the bug pattern is applied.

 import static com.google.common.base.Preconditions.checkArgument;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.Locale;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Marker;
 
 class A {
   private static final Logger LOG = LoggerFactory.getLogger(A.class);
 
   void assertj() {
-    assertThat(0).overridingErrorMessage(toString() + " str");
-    assertThat(0).overridingErrorMessage("str " + toString());
-    assertThat(0).overridingErrorMessage(toString() + toString());
-    assertThat(0).overridingErrorMessage("str " + toString() + " word " + new A().hashCode());
-    assertThat(0).overridingErrorMessage("str " + (toString() + " word ") + (hashCode() / 2));
+    assertThat(0).overridingErrorMessage("%s str", toString());
+    assertThat(0).overridingErrorMessage("str %s", toString());
+    assertThat(0).overridingErrorMessage("%s%s", toString(), toString());
+    assertThat(0).overridingErrorMessage("str %s word %s", toString(), new A().hashCode());
+    assertThat(0).overridingErrorMessage("str %s word %s", toString(), hashCode() / 2);
 
     // Flagged but not auto-fixed.
     assertThat(0).overridingErrorMessage("%s " + toString(), "arg");
   }
 
   void guava() {
-    checkArgument(true, "str " + toString());
+    checkArgument(true, "str %s", toString());
 
     // Flagged but not auto-fixed.
     checkArgument(true, "%s " + toString(), "arg");
   }
 
   void jdk() {
-    String.format("str " + toString());
-    String.format(Locale.ROOT, "str " + toString());
+    String.format("str %s", toString());
+    String.format(Locale.ROOT, "str %s", toString());
 
     // Flagged but not auto-fixed.
     String.format("{} " + toString(), "arg");
     String.format(Locale.ROOT, "{} " + toString(), "arg");
   }
 
   void slf4j() {
-    LOG.debug("str " + toString());
-    LOG.debug((Marker) null, "str " + toString());
+    LOG.debug("str {}", toString());
+    LOG.debug((Marker) null, "str {}", toString());
 
     // Flagged but not auto-fixed.
     LOG.debug("{} " + toString(), "arg");
     LOG.debug((Marker) null, "{} " + toString(), "arg");
   }
 }

Identification

Shows code lines which will (not) be flagged by this bug pattern.
A //BUG: Diagnostic contains: comment is placed above any violating line.

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Verify.verify;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.SoftAssertions.assertSoftly;

import java.util.Formatter;
import java.util.Locale;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.BDDAssertions;
import org.assertj.core.api.Fail;
import org.assertj.core.api.ThrowableAssertAlternative;
import org.assertj.core.api.WithAssertions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;

class A {
  private static final Logger LOG = LoggerFactory.getLogger(A.class);

  void negative() {
    hashCode();
    equals(new A());
    equals(toString());
    equals(0);
    equals("str");
    equals("str" + 0);
    equals(0 + 0);
    equals(0 - 0);
    equals("str " + toString());
  }

  void assertj() {
    assertThat(0).overridingErrorMessage(toString());
    assertThat(0).overridingErrorMessage("str");
    assertThat(0).overridingErrorMessage("str " + 0);
    assertThat(0).overridingErrorMessage("str %s", 2 * 3);
    assertThat(0).overridingErrorMessage("str %s", toString());
    // BUG: Diagnostic contains:
    assertThat(0).overridingErrorMessage("str " + hashCode() / 2);
    // BUG: Diagnostic contains:
    assertThat(0).overridingErrorMessage(("str " + toString()));
    // BUG: Diagnostic contains:
    assertThat(0).overridingErrorMessage("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(0).overridingErrorMessage("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(0).withFailMessage("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(0).withFailMessage("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertSoftly(softly -> softly.fail("str " + toString()));
    // BUG: Diagnostic contains:
    assertSoftly(softly -> softly.fail("%s " + toString(), "arg"));
    assertSoftly(softly -> softly.fail("str " + toString(), new Throwable()));

    // BUG: Diagnostic contains:
    assertThat("").isEqualTo("str " + toString());
    // BUG: Diagnostic contains:
    assertThat("").isEqualTo("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessage("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessage("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessageContaining("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessageContaining("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessageEndingWith("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessageEndingWith("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessageStartingWith("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(new Error()).hasMessageStartingWith("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(new Error()).hasRootCauseMessage("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(new Error()).hasRootCauseMessage("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(new Error()).hasStackTraceContaining("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(new Error()).hasStackTraceContaining("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(0).as("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(0).as("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    assertThat(0).describedAs("str " + toString());
    // BUG: Diagnostic contains:
    assertThat(0).describedAs("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessage("str " + toString());
    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessage("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessageContaining("str " + toString());
    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessageContaining("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessageEndingWith("str " + toString());
    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessageEndingWith("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessageStartingWith("str " + toString());
    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withMessageStartingWith("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withStackTraceContaining("str " + toString());
    // BUG: Diagnostic contains:
    ((ThrowableAssertAlternative) null).withStackTraceContaining("%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    ((WithAssertions) null).fail("str " + toString());
    // BUG: Diagnostic contains:
    ((WithAssertions) null).fail("%s " + toString(), "arg");
    ((WithAssertions) null).fail("str " + toString(), new Throwable());

    // BUG: Diagnostic contains:
    Assertions.fail("str " + toString());
    // BUG: Diagnostic contains:
    Assertions.fail("%s " + toString(), "arg");
    Assertions.fail("str " + toString(), new Throwable());

    // BUG: Diagnostic contains:
    BDDAssertions.fail("str " + toString());
    // BUG: Diagnostic contains:
    BDDAssertions.fail("%s " + toString(), "arg");
    BDDAssertions.fail("str " + toString(), new Throwable());

    // BUG: Diagnostic contains:
    Fail.fail("str " + toString());
    // BUG: Diagnostic contains:
    Fail.fail("%s " + toString(), "arg");
    Fail.fail("str " + toString(), new Throwable());
  }

  void guava() {
    checkArgument(true);
    checkArgument(true, toString());
    checkArgument(true, "str");
    checkArgument(true, "str " + 0);
    checkArgument(true, "str %s", 2 * 3);
    checkArgument(true, "str %s", toString());
    // BUG: Diagnostic contains:
    checkArgument(true, "str " + hashCode() / 2);
    // BUG: Diagnostic contains:
    checkArgument(true, ("str " + toString()));
    // BUG: Diagnostic contains:
    checkArgument(true, "str " + toString());
    // BUG: Diagnostic contains:
    checkArgument(true, "%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    checkNotNull(true, "str " + toString());
    // BUG: Diagnostic contains:
    checkNotNull(true, "%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    checkState(true, "str " + toString());
    // BUG: Diagnostic contains:
    checkState(true, "%s " + toString(), "arg");

    // BUG: Diagnostic contains:
    verify(true, "str " + toString());
    // BUG: Diagnostic contains:
    verify(true, "%s " + toString(), "arg");
  }

  void jdk() {
    String.format("str");
    String.format("str " + 0);
    String.format("str {}", 2 * 3);
    String.format("str {}", toString());
    // BUG: Diagnostic contains:
    String.format("str " + hashCode() / 2);
    // BUG: Diagnostic contains:
    String.format(("str " + toString()));
    // BUG: Diagnostic contains:
    String.format("str " + toString());
    // BUG: Diagnostic contains:
    String.format("{} " + toString(), "arg");

    String.format(Locale.ROOT, "str");
    String.format(Locale.ROOT, "str " + 0);
    String.format(Locale.ROOT, "str {}", 2 * 3);
    String.format(Locale.ROOT, "str {}", toString());
    // BUG: Diagnostic contains:
    String.format(Locale.ROOT, ("str " + toString()));
    // BUG: Diagnostic contains:
    String.format(Locale.ROOT, "str " + toString());
    // BUG: Diagnostic contains:
    String.format(Locale.ROOT, "{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    new Formatter().format("str " + toString());
    // BUG: Diagnostic contains:
    new Formatter().format("{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    new Formatter().format(Locale.ROOT, "str " + toString());
    // BUG: Diagnostic contains:
    new Formatter().format(Locale.ROOT, "{} " + toString(), "arg");
  }

  void slf4j() {
    LOG.debug("str");
    LOG.debug("str " + 0);
    LOG.debug("str {}", 2 * 3);
    LOG.debug("str {}", toString());
    // BUG: Diagnostic contains:
    LOG.debug("str " + hashCode() / 2);
    // BUG: Diagnostic contains:
    LOG.debug(("str " + toString()));
    // BUG: Diagnostic contains:
    LOG.debug("str " + toString());
    // BUG: Diagnostic contains:
    LOG.debug("{} " + toString(), "arg");

    LOG.debug((Marker) null, "str");
    LOG.debug((Marker) null, "str " + 0);
    LOG.debug((Marker) null, "str {}", 2 * 3);
    LOG.debug((Marker) null, "str {}", toString());
    // BUG: Diagnostic contains:
    LOG.debug((Marker) null, ("str " + toString()));
    // BUG: Diagnostic contains:
    LOG.debug((Marker) null, "str " + toString());
    // BUG: Diagnostic contains:
    LOG.debug((Marker) null, "{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.error("str " + toString());
    // BUG: Diagnostic contains:
    LOG.error("{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.error((Marker) null, "str " + toString());
    // BUG: Diagnostic contains:
    LOG.error((Marker) null, "{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.info("str " + toString());
    // BUG: Diagnostic contains:
    LOG.info("{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.info((Marker) null, "str " + toString());
    // BUG: Diagnostic contains:
    LOG.info((Marker) null, "{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.trace("str " + toString());
    // BUG: Diagnostic contains:
    LOG.trace("{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.trace((Marker) null, "str " + toString());
    // BUG: Diagnostic contains:
    LOG.trace((Marker) null, "{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.warn("str " + toString());
    // BUG: Diagnostic contains:
    LOG.warn("{} " + toString(), "arg");

    // BUG: Diagnostic contains:
    LOG.warn((Marker) null, "str " + toString());
    // BUG: Diagnostic contains:
    LOG.warn((Marker) null, "{} " + toString(), "arg");
  }
}

Copyright © 2017-2023 Picnic Technologies BV