Передать аргумент конструктора в статический блок

У меня есть такой класс

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 поле пустое Понятия не имею, что я делаю не так

3 ответа

Решение

статический блок выполняется перед созданием 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")

Или (без статики) переместить метод в конструктор с аргументом String

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();
    }

}

Это не работает, потому что static Блок выполняется во время инициализации класса, прежде чем будет создан какой-либо экземпляр или запущен конструктор.

И нет способа передать параметры в это. Единственное, что он может сделать, это загрузить статическое значение из другого места, которое вы настроили первым. Чтение из внешней конфигурации (системные свойства и т. Д.) Также является опцией.

Вы, вероятно, захотите заменить свои статические объекты одноэлементным экземпляром (возможно, статическим методом для его инициализации) - или, что еще лучше, "обычным" экземпляром, который затем можно внедрить в качестве зависимости в любой код, необходимый для использования вашего CustomRestClient (это облегчит работу, если вам когда-нибудь понадобится работать с несколькими наборами настроек соединения).

Неправильно помещать этот блок кода в блок статического инициализатора, поскольку он зависит от параметра конструктора, который передается в конструктор после выполнения статического блока.

Если эта инициализация зависит от конкретного параметра экземпляра (разные экземпляры CustomRestClient может получить разные dbStrings) его следует перенести в метод экземпляра (т.е. static).

С другой стороны, если dbString должен оставаться static переменная, она должна быть инициализирована некоторыми static метод, а не конструктор. В этом случае ваш static блок инициализатора должен быть перемещен к этому static метод. Это будет ваша ответственность, чтобы выполнить это static метод.

Другие вопросы по тегам