定义常量的 Sonar 方法

The Sonar way to define a constant

我使用 Sonarqube 5.1 并尝试使用“Sonar Way”Java 质量配置文件。工作很简单:我想为缺少的媒体类型定义一个 global 字符串常量:

public interface Utf8MediaType {
    String APPLICATION_JSON = "application/json;charset=UTF-8";
}

然而,Sonarqube 告诉我这是规则 squid:S1214 中的不良做法 – 常量不应在接口 中定义。长篇大论说要实现这个接口,我不是有意为之,但我让步了,改为创建一个class:

public class Utf8MediaType {
    public static final String APPLICATION_JSON = "application/json;charset=UTF-8";
}

然而,这被认为是规则 squid:S1118 中的一个主要设计问题 – 实用程序 classes 不应该有 public 构造函数 。所以它敦促我添加一个私有构造函数。当然,这个构造函数首先必须不违反规则 squid:S1213 中的约定——接口声明或 class 的成员应该以预定义的顺序出现 .我想在那之后我什至可能会得到 common-java:InsufficientBranchCoverage 因为私有构造函数没有包含在测试中。


这些是默认规则,我觉得它们结合起来有点傻。我有更多示例,其中默认设置对我们不起作用(缺少 TestNG 支持)。 我该怎么办?你有什么建议?

Give in. Make it a class, add a private constructor, use introspection in the unit test. Makes the code ten times as big. For a String constant.

这是大体上正确的做法。您真的不想创建 "Constants" 界面。需要私有构造函数来确保用户不会无意中扩展或实例化不应实例化的对象。

How to add test coverage to a private constructor?

Create a list of exceptions. But doing this for each project may lead to long lists and invites people to add exceptions even for important stuff.

工作量太大。

Deactivate rules. Now I would prefer not to tamper with the default profiles, because that may mean a lot of work on Sonarqube upgrades.

就像你说的……坏主意。

Create a profile that inherits from the default and overwrites things. It turns out that when you inherit from a profile you cannot deactivate rules. You can only add additional rules and change the configuration of rules (to lower their severity).

如果您将严重性设置为 "info",它将从技术债务计算中移除。我必须使用 squid:S1213 来做到这一点,当我使用 Eclipse 指定的默认顺序进行排序时会引发该问题。

问这个问题已经有几年了,但 sonarlint 仍在抱怨

public interface Utf8MediaType {
    String APPLICATION_JSON = "application/json;charset=UTF-8";
}

现在 sonarlint 提议

public final class Utf8MediaType {
    public static final String APPLICATION_JSON = "application/json;charset=UTF-8";
}

但我仍然不喜欢使用 interface 时不需要的这些 "extra" public static final。在我们的项目中,我们过渡到 Kotlin,这可以逐个文件地完成,方法是:

object Utf8MediaType {
    const val APPLICATION_JSON = "application/json;charset=UTF-8"
}

比 Java 界面还要短。