【问题标题】:The Sonar way to define a constantSonar 定义常量的方法
【发布时间】:2015-08-11 22:58:21
【问题描述】:

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

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

然而,Sonarqube 告诉我这是规则 squid:S1214 中的不好做法——不应在接口中定义常量。长篇大论讲的是实现这个接口,我本来不打算这么做的,但我放弃并创建了一个类:

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

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


这些是默认规则,我觉得它们组合起来有点傻。我有更多默认设置对我们不起作用的示例(缺少对 TestNG 的支持)。 我能做些什么呢?你有什么推荐的?

  • 让步。让它成为一个类,添加一个私有构造函数,在单元测试中使用自省。使代码大十倍。对于字符串常量。
  • 创建一个例外列表。但为每个项目执行此操作可能会导致列表过长,并邀请人们添加例外,即使是重要的东西。
  • 停用规则。现在我希望不要篡改默认配置文件,因为这可能意味着在 Sonarqube 升级方面需要做大量工作。
  • 创建一个从默认继承并覆盖内容的配置文件。事实证明,当您从配置文件继承时,您不能停用 规则。您只能添加其他规则并更改规则配置(以降低其严重性)。

【问题讨论】:

  • “你不能禁用规则”
  • 好吧,@fge,如果我知道怎么做,我会去做。那是我个人的喜好。
  • 以管理员身份登录,单击“规则”选项卡,选择您使用的配置文件,找到规则并单击“停用”按钮...
  • 我的 Sonarqube 版本中没有“停用”按钮。请注意,我提到了从另一个配置文件继承的配置文件。当我的配置文件“My way”继承自“Sonar way”时,该按钮仅位于规则的“Sonar way”行上。
  • 媒体类型用作某些注释的值。因此它们必须是字符串,并且必须是编译时常量。

标签: java sonarqube


【解决方案1】:

放弃吧。让它成为一个类,添加一个私有构造函数,在单元测试中使用自省。使代码大十倍。对于字符串常量。

这通常是正确的方法。您真的不想创建“常量”界面。需要私有构造函数来确保用户不会无意中扩展或实例化不应实例化的对象。

How to add test coverage to a private constructor?

创建一个例外列表。但是为每个项目这样做可能会导致列表很长,并邀请人们添加例外,即使是重要的东西。

工作量太大。

停用规则。现在我不想篡改默认配置文件,因为这可能意味着在 Sonarqube 升级方面需要做大量工作。

正如你所说的……坏主意。

创建一个从默认值继承并覆盖内容的配置文件。事实证明,当您从配置文件继承时,您无法停用规则。您只能添加额外的规则并更改规则的配置(以降低其严重性)。

如果您将严重性设置为“信息”,则会将其从技术债务计算中删除。我必须使用squid:S1213 来执行此操作,当我使用 Eclipse 指定的默认顺序进行排序时会引发该问题。

【讨论】:

    【解决方案2】:

    自从有人问这个问题以来已经有几年了,但 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 时不需要的这些“额外”public static final。在我们的项目中,我们过渡到 Kotlin,这可以逐个文件完成,方法是:

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

    它比 Java 接口还要短。

    【讨论】:

    • 虽然这根本不能解决我的 Java 问题,但您使用 Kotlin 从我这里得到了一个很大的YES。我只需要再等一会儿,直到我的雇主正式允许它作为 Java 替代品。
    • 我必须说,作为一名 Android 开发人员,我被 Google 严重欺骗了。 Java11 更像 Kotlin,而不是我们在 Android 上坚持使用的 Java8。但是,如果您使用的是 Android,则没有理由不迁移到 Kotlin。根据 Google 的说法,这是官方的方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 2015-11-18
    • 2012-11-10
    相关资源
    最近更新 更多