Reputation: 2052
I have a class like this
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");
}
}
I'm trying to pass the constructor argument inside the static block
provider.setCredentialsProvider(new SimpleCredentialsProvider("user", "pass", dbString, "secretkey"));
For example, CustomRestClient customRestClient = new CustomRestClient("db");
should set the dbString
field inside the static block to db
. But when I run the program it says the dbString
field is null. I have no idea what I'm doing wrong
Upvotes: 2
Views: 602
Reputation: 58772
static block is executed before you create the CustomRestClient
object
You should move the static block to static method and call it
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();
}
And call it:
CustomRestClient.login("db")
Or (without static) move the method inside a constructor with String argument
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();
}
}
Upvotes: 2
Reputation: 262534
That does not work because the static
block runs during initialization of the class, before any instance is created or constructor runs.
And there is no way to pass parameters into that. The only thing it could do is load a static value from another place that you set up first. Reading from external configuration (system properties and such) is also an option.
You probably want to replace your static things with a singleton instance (with maybe a static method to initialize it) --- or even better a "regular" instance that you can then inject as a dependency into whatever code needs to use your CustomRestClient
(that would make it easier if you ever need to work with multiple sets of connection settings).
Upvotes: 1
Reputation: 393851
It's wrong to put that block of code in a static initializer block, since it depends on a constructor parameter, which is passed to the constructor after the static block is executed.
If that initialization depends on an instance specific parameter (different instances of CustomRestClient
can receive different dbString
s), it should be moved to an instance method (i.e. not static
).
On the other hand, if dbString
should remain a static
variable, it should be initialized by some static
method, not the constructor. In that case, your static
initializer block should be moved to that static
method. It would be your responsibility to execute that static
method.
Upvotes: 1