Передать аргумент конструктора в статический блок
У меня есть такой класс
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
может получить разные dbString
s) его следует перенести в метод экземпляра (т.е. static
).
С другой стороны, если dbString
должен оставаться static
переменная, она должна быть инициализирована некоторыми static
метод, а не конструктор. В этом случае ваш static
блок инициализатора должен быть перемещен к этому static
метод. Это будет ваша ответственность, чтобы выполнить это static
метод.