【问题标题】:Pass a constructor argument to a static block将构造函数参数传递给静态块
【发布时间】:2019-04-25 01:29:46
【问题描述】:

我有这样的课

public class CustomRestClient {

private static String dbString;

public CustomRestClient(String db) {
    this.dbString = db;
}

static {       
    try {
        Client.setServer(Client.Server.LOCAL);
        AuthenticationProvider provider = new AuthenticationProvider();
        provider.setCredentialsProvider(new SimpleCredentialsProvider("user", "pass", dbString, "secretkey"));
        Client.setAuthenticationProvider(provider);
        Client.login();
    } catch (ClientException e) {
        e.printStackTrace();
    }
}

public static void main(String[] args) {
    CustomRestClient customRestClient = new CustomRestClient("db");
 }
}

我正在尝试在静态块中传递构造函数参数

provider.setCredentialsProvider(new SimpleCredentialsProvider("user", "pass", dbString, "secretkey"));

例如,CustomRestClient customRestClient = new CustomRestClient("db"); 应将静态块内的dbString 字段设置为db。但是当我运行程序时,它说dbString 字段为空。我不知道我做错了什么

【问题讨论】:

  • 静态块在构造函数执行之前运行。你试图做的事情是不可能的

标签: java constructor static static-block


【解决方案1】:

static block 在创建 CustomRestClient 对象之前执行

您应该将静态块移动到静态方法并调用它

public static void login(String db) {
        Client.setServer(Client.Server.LOCAL);
        AuthenticationProvider provider = new AuthenticationProvider();
        provider.setCredentialsProvider(new SimpleCredentialsProvider("user", "pass", dbString, "secretkey"));
        Client.setAuthenticationProvider(provider);
        Client.login();
}

并称它为:

CustomRestClient.login("db")

或者(不带静态)在带有字符串参数的构造函数中移动方法

private String dbString;

public CustomRestClient(String db) {
    this.dbString = db;
    try {
        Client.setServer(Client.Server.LOCAL);
        AuthenticationProvider provider = new AuthenticationProvider();
        provider.setCredentialsProvider(new SimpleCredentialsProvider("user", "pass", dbString, "secretkey"));
        Client.setAuthenticationProvider(provider);
        Client.login();
    } catch (ClientException e) {
        e.printStackTrace();
    }

}

【讨论】:

  • 感谢您的解释。现在,我对静态块的工作原理有了更多了解。
  • 需要指出的是,最终选项通常是不被接受的。由于在构造函数内部进行工作,尤其是调用静态方法,因此很难测试一个类。
  • @MattWatson 是的,您可以在构造函数之后调用专用方法
【解决方案2】:

这不起作用,因为 static 块在类的初始化期间运行,在任何实例被创建或构造函数运行之前。

而且没有办法将参数传递给它。它唯一能做的就是从您首先设置的另一个地方加载一个静态值。从外部配置(系统属性等)读取也是一种选择。

您可能想用单例实例(可能使用静态方法来初始化它)替换您的静态事物 --- 或者甚至更好的“常规”实例,然后您可以将其作为依赖项注入到需要使用的任何代码中您的CustomRestClient(如果您需要使用多组连接设置,这会更容易)。

【讨论】:

    【解决方案3】:

    将代码块放在静态初始化块中是错误的,因为它依赖于构造函数参数,该参数在静态块执行后传递给构造函数。

    如果该初始化依赖于特定于实例的参数(CustomRestClient 的不同实例可以接收不同的dbStrings),则应将其移至实例方法(即不是static)。

    另一方面,如果dbString 应该保持为static 变量,它应该由一些static 方法初始化,而不是构造函数。在这种情况下,您的 static 初始化程序块应移至该 static 方法。执行 static 方法是您的责任。

    【讨论】:

      猜你喜欢
      • 2013-12-23
      • 2012-02-21
      • 2016-03-17
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多