Sonar 抱怨:使用 StringBuilder 而不是 StringBuffer

Sonar complains : use StringBuilder instead of StringBuffer

我目前正在编写一段代码,它必须能够匹配一些正则表达式并在匹配正则表达式的字符串中进行一些替换。

为了做到这一点,我在 java 中使用了 matcher 对象。但 正如您在互联网上看到的那样,所有示例都使用 StringBuffer 以便使用 appendreplacement 和 appendtail 方法 (oracleDoc) 进行一些替换。

但是当我推送我的代码时,Sonar 抱怨使用 stringbuffer 而不是 stringbuilder。

显然一些开发者抱怨 here

我找到了一种不使用 StringBuffer 而使用 StringBuilder 的方法,但我很确定这不如使用 StringBuffer 有效(并且可能是一种不好的做法)。您可以在下面的示例代码中复制粘贴到 junit 测试中:

    String entry = "Actual 4.11-6 and 13-5";
    String expectedReturn = "Actual 4*11^(-6) and 13^(-5)";

    String number = "(^|\s)-?\d+((\.||,)\d+){0,1}(.\d+){0,1}-\d+";
    Pattern pattern = Pattern.compile(number);
    Matcher matcher = pattern.matcher(entry);

    //USING STRING BUFFER
    StringBuffer stringBuffer = new StringBuffer();
    String substring;
    while(matcher.find()){
        substring = matcher.group(0);
        matcher.appendReplacement(stringBuffer,substring.replace(".","*").replace("-","^(-")+")");
    }
    matcher.appendTail(stringBuffer);

    //USING STRING BUILDER
    matcher = pattern.matcher(entry);
    int lastIndex = 0;
    StringBuilder stringBuilder = new StringBuilder();
    while(matcher.find()){
        stringBuilder.append(entry.substring(lastIndex,matcher.start()));
        substring = matcher.group(0);
        stringBuilder.append(substring.replace(".","*").replace("-","^(-")+")");
        lastIndex = matcher.end();
    }
    stringBuilder.append(entry.substring(lastIndex,entry.length()));

    Assert.assertEquals(expectedReturn,stringBuffer.toString());
    Assert.assertEquals(expectedReturn,stringBuilder.toString());

信息:为追加管理 stringbuilder 的匹配器将在 jdk 9 source code and code review

这是警告,不是错误。 Sonar 会警告您 StringBuilder 更可取 because it is faster。如果 API 强制您使用 StringBuffer 那么我会使用它并使警告静音。

我认为 Pattern 和两个缓冲区的真正潜在问题是 StringBufferStringBuilder 不共享构建字符串的特定接口(Appendable 是一个更通用的接口,我认为他们应该共享一个更具体的接口来构造字符串,比如 StringConstructor),这将允许您以零努力(通常)切换实现。