【问题标题】:Code smell sonarLint - Assigning a value to a static field代码气味 sonarLint - 为静态字段分配值
【发布时间】:2018-06-29 12:00:59
【问题描述】:

你能改变它来满足 sonarLint 吗?如果我不做赋值,我的变量的值为 null ...

@SpringBootApplication
public class BwsApplication {
    private static ConfigClass config;

    public BwsApplication(ConfigClass configClass) {
        config = configClass;//SONAR - Remove this assignment of "config"
    }

    public static void main(String[] args) throws SQLException {
        SpringApplication.run(BwsApplication.class, args);
        Connection con = config.getConnection();
        int number = StudentsManager.getStudentsNumber(con);
        QuartzApp qa = new QuartzApp(config);
        qa.excecution(number );
    }
}

“静态字段不应在构造函数中更新” 我需要在静态上下文中使用变量!

【问题讨论】:

  • 您可以声明public static void init(ConfigClass configClass) { config = configClass; },而不是在构造函数中进行赋值。如果您知道只有一个 BwsApplication 实例存在,请将其设为 Singleton
  • 这有什么意义?你明白为什么在构造函数中更新静态字段没有意义吗?你是什​​么意思,你需要在静态上下文中使用变量,为什么你需要为每个实例更改它(另外:现有实例是否应该与传递给新实例的值相同)?跨度>

标签: java spring-boot


【解决方案1】:

该类使用@SpringBootApplication进行注释。
作为记录,以下是 Spring Boot 在创建 bean 应用程序期间调用的构造函数:

public BwsApplication(ConfigClass configClass) {
    config = configClass;//SONAR - Remove this assignment of "config"
}

这个类所代表的SpringBootApplication只会被实例化一次。所以从逻辑上看,将这个字段设为static字段似乎并没有什么不妥。但事实上,将其设为 static 或 no 并不重要,因为它将与不超过一个实例共享。将其设为static,您将不遗余力。
我认为您创建了 static 字段,因为您将在 static 主要方法中使用它。
但这不是这样做的方法。
相反,删除 static 修饰符并将此代码移动到实例 @PostConstruct 方法中,该方法将在对此 bean 执行依赖注入后执行:

Connection con = config.getConnection();
int number = StudentsManager.getStudentsNumber(con);
QuartzApp qa = new QuartzApp(config);
qa.excecution(number );

这样,您可以引用config 字段,即使它是一个实例字段。

它可能看起来像:

@SpringBootApplication
public class BwsApplication {

    private  ConfigClass config;

    public BwsApplication(ConfigClass configClass) {
        config = configClass;//SONAR - Remove this assignment of "config"
    }

    public static void main(String[] args) throws SQLException {
        SpringApplication.run(BwsApplication.class, args);       
    }

    @PostConstruct
    private void postConstruct() {
      Connection con = config.getConnection();
      int number = StudentsManager.getStudentsNumber(con);
      QuartzApp qa = new QuartzApp(config);
      qa.excecution(number);
    }
}

【讨论】:

  • @Manzini 如果解释对您有价值,那就太好了:-)
【解决方案2】:

此代码看起来很奇怪,SonarLint 报告代码异味是正确的。您的字段config 被声明为static,即它由BwsApplication 的所有实例共享。每次构造函数调用都需要一个新的 ConfigClass 实例并覆盖 static 字段很可能不是您想要的。

您可以通过在某些静态方法中进行分配来解决此问题,例如:

public class BwsApplication {
  private static ConfigClass config;
  ...
  public static final void init(final ConfigClass configClass) {
    config = configClass;
  }
}

您的构造函数将不再需要ConfigClass 类型的参数。


如果您可以在编译时确定config 的实例,则可以部署JohnSnowDoesNotKnowNothing's solution 并部署静态初始化程序块。


只是为了排除这种可能性:请确保您没有将staticfinal 混淆。

【讨论】:

  • 一般是的,但它是一个 Spring Boot 应用程序类。 static 修饰符是与main() 方法中的字段交互的解决方法。你可以参考我的回答来理解。
猜你喜欢
  • 2018-10-05
  • 2017-10-30
  • 1970-01-01
  • 1970-01-01
  • 2021-01-07
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多