Передать аргумент конструктора в статический блок - PullRequest
0 голосов
/ 22 ноября 2018

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

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 ]

0 голосов
/ 22 ноября 2018

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

и вызватьit:

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

}

0 голосов
/ 22 ноября 2018

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

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

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

0 голосов
/ 22 ноября 2018

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

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

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

...