Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I was wondering whether it is possible to call a static method from a static block in order to initialize static variables. Is e.g. the following possible:
public class AppProperties {
private static final Logger logger = LoggerFactory.getLogger(AppProperties.class);
private static final String PARSER_PROPERTIES_FILE = "/parser.properties";
private static final Properties PARSER_PROPERTIES = new Properties();
private static final Properties DAO_PROPERTIES = new Properties();
static {
loadParserProperties();
loadDaoProperties();
// Some other configuration
}
public static void loadParserProperties() {
// Loading parser properties
}
// Further methods omitted
}
Is it good practice?
EDIT:
Oracle recommends initialization as follows:
class Whatever {
public static VarType myVar = initializeClassVariable();
private static VarType initializeClassVariable() {
// Initialization code goes here
}
}
Their explanation is:
The advantage of private static methods is that they can be reused
later if you need to reinitialize the class variable.
However, the AppProperties code is also reusable. I have a feeling that I am missing something. Calling static methods from static blocks isn't mentioned, that's why I assume it is bad practice.
Static block call your method only once at time of class creation, If you want to call method at time of class creation you can call it.
Static block is only way by which you can call your static methods at time of class creation.
This should not be any issue related to design or best practice.
Anyways, it is advisable to divide chunk of code/functionality into different functions, and making them static and calling from static block is something your applications demands during loading of class by JVM.
The advantage of static methods is that they can be reused later if you need . So, you kind of get more flexibility with a static method in comparison to the corresponding static initialization block.
for more info here
Calling to static method from static block it acceptable in the case of you really want to execute the content in the referred static method only one time when the class is getting initialize in the JVM first time. Further you have to keep it in mind this static block won't ever execute again even though you created multiple object in same type with in your application except the first creation.
However you have to use static variables to store if there any values need to be use with the other object creation cycles.
Some extra points about static block might help someone.
Calling static methods inside of static block is accepted only in below conditions.
1) It must contain main method if the java version is 7 or above. Else it will throw below error
Error: Main method not found in class MyClass, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
2) If java version is 6 or below, it will work fine even if we don't have main method.
Example :
// The below code would not work in JDK 1.7 and above
class staticExample {
// static block execution without main method in JDK 1.6.
static
{
System.out.println("Inside Static Block.");
System.exit(0);
}
}
Output:(In JDK 1.6)
Inside Static Block.
But from JDK 1.7 onwards the above code gives an error in output.
Output:
Error: Main method not found in class staticExample, please define the main method as:
public static void main(String args[])
or a JavaFX application class must extend javafx.application.Application
You can do this. But it is not the best idea for a couple reasons.
One is that you have hard-wired your class to whatever property files the static method is reading, complicating testing. You can't exercise the class without having the actual files present.
Another is that exception-handling in static blocks is problematic, there's no way to handle an unchecked exception thrown from a static block. See Why doesn't Java allow to throw a checked exception from static initialization block?. You would have to specifically catch everything coming out of the block, and anything that was missed couldn't be caught anywhere in the application.
Dependency injection frameworks will handle injecting this stuff into your classes for you with easier testing and no exception-handling issues.
Related
If seen this question here:
Instance initializer and *this* keyword
and now I ask myself is something like this:
public class Main {
public static void main(String args[]) {
new Main();
}
{ System.out.println(x); } //Error here
int x=1;
}
of any (even just theoritical) use? I mean this part:
{ System.out.println(x); } //Error here
As far as I can say its anonymous so I'd have no idea how to execute it manually, it doesn't seem to be executed automatically is not part of any function or whatsoever. Sorry if this questions is already answered, but the ones that I found targeted {} to restrict the variable scope but in this case I could not think of a way to get into that scope or make it run.
It's an instance initialization block. Whenever you create an instance of the class, it is executed before the body of the constructor you use.
Therefore the only way to execute it manually is by creating an instance of the class in which this block appears (or a sub-class of that class).
What makes public static void main(String args[]) {} be the convention to test code instead of simply static {}?
class Test {
public static void main(String args[]) {
System.out.println("testing");
}
}
It seemingly has the same capabilities, you can instantiate owner class, use its methods, another classes, even send output as well:
class Test {
static {
System.out.println("testing");
}
}
Is there a standard reason to not use the small static {} to run your average test? Can I take it just as my choice/preference safely?
In other words, I'd like to find a case where you put a code in one that you couldn't (or shouldn't) put in another, that it wouldn't run or give unexpected result, etc.
I'd say the most prominent reason not to use static {} for such things is that you have little control over when it runs. static {} blocks run "when the class is initialized", which means at least four (watch out for the Spanish inquisition) detrimental things for this purpose:
It does not necessarily happen just because the class is loaded.
It does, on the other hand, happen just because you want an instance of the class or reference a static field from some other class, which is the main reason why you don't really want to put code with wide-ranging side-effects in static {} blocks.
It is also not guaranteed to not happen for such simple reasons as the Jar file being on your classpath. JVMs are free to run static {} blocks whenever they feel like it, as long as it is before any static references from the class from other code is made. "Before" could mean "at VM startup".
No VM implementation has any invocation arguments to run such code for you on request.
The purpose of static {} blocks is to initialize static class data (in possibly quite complex ways, of course), and from the preceding points you may be able to see why it's not particularly useful for anything else.
In java every application requires a main method which will be the entry point of the application. The main method required has the signature as follows:
public static void main(String[] args)
The difference between this method and the other one you suggested (besides the fact that your application needs a main method with this signature as an entry point) is that this is a method and takes the "String[] args" parameter. This parameter is where your arguments would go when running a program from the console.
Every java application can be run from the console and therefore it makes sense for every application to have a standard entry point method which will be able to take any special arguments.
Your static {} block is not necessarily a method or a function that can be called and therefore it can not be used as a entry point into your application. It takes no parameters and you have no control over when its code block will be run.
My projects had some developer who loved a static initialization block. What is the alternative to this? What is the downside of this alternative?
public class BlockTest {
String test = new String();
static{
test = "test string";
}
}
As far as I understood the static initialization block is used to set values of static field if it cannot be done in one line. But I do not understand why we need a special block for that. This leads to less readability and some confusion.
The example is not good. First of all it does not compile, you cannot assign a instance variable from static init block. But if even it were correct
public class BlockTest {
static String test = new String();
static{
test = "test string";
}
it would make no sense since it is equivalent to
public class BlockTest {
static String test = "test string";
but this static init block has no alternative
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
...
It can be used for performing all the tasks that needs to be done when the class is referred for the first time, even before the instances of the class are created. It could have call to different methods or just initialization of static members. Static block ensures that these activities will be performed only once in the lifetime of the class and will be performed before any other operation takes place with regard to the class.
Programmer can depend on static block as it is ensured that the block will be executed only once and before any other activity related to that class is performed.
Moreover, I do not think it hampers readability at all. It again may vary from person to person.
If you have static members in your class which require a longer handling, you won't get around a static initializer (constructor). These must be initialized somewhere after all. You could do that in the constructor of your class, but then you would reinitialize these values EVERYTIME you create a new object.
There is no real alternative if you must handle more than just a simple initialization.
See this post and this.
If you have simple assignments, you can do the assignment directly in the member declaration. No need for a separate block which just extends the complexity and readabillity.
An alternative would be to use a lazy initialization. Advantage is that it can also be arbitrary complex, but is only executed when actually needed. But of course this only works if you have getters in your classes. If you access the members directly, then this would be a big change.
IMHO,There is no need for static block.
String test = "test string";
And From docs
Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.
But
Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
The community reviewed whether to reopen this question last year and left it closed:
Original close reason(s) were not resolved
What is the best and cleanest way to do this? Specifically, I need some code in a static initializer block to run in that class, but I'd like to make this as clean-looking as possible.
Loading != Initialization.
You want your class to be initialized (this is when static blocks executed, among other things).
An excerpt from the Java Language Specification says:
A class or interface type T will be initialized immediately before the first occurrence of >any one of the following:
T is a class and an instance of T is created.
T is a class and a static method declared by T is invoked.
A static field declared by T is assigned.
A static field declared by T is used and the field is not a constant variable (§4.12.4).
T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.
Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.
Doh, anovstrup, already said it: Just make an empty static function called init. Be sure to document that well... I personally can't see any use case for this in the context of well formed code though.
You can use the following code to force initialization of a class:
//... Foo.class ... //OLD CODE
... forceInit(Foo.class) ... //NEW CODE
/**
* Forces the initialization of the class pertaining to
* the specified <tt>Class</tt> object.
* This method does nothing if the class is already
* initialized prior to invocation.
*
* #param klass the class for which to force initialization
* #return <tt>klass</tt>
*/
public static <T> Class<T> forceInit(Class<T> klass) {
try {
Class.forName(klass.getName(), true, klass.getClassLoader());
} catch (ClassNotFoundException e) {
throw new AssertionError(e); // Can't happen
}
return klass;
}
try
{
Class.forName(class name as string)
}
catch(ClassNotFoundException e)
{
whatever
}
That should do it.
#Longpoke
Maybe I am misunderstanding something then. Can you create an example where a class is loaded but the static initializer is not executed? Here is an example that does nothing but print out that it has loaded:
package test;
public class TestStatic
{
public static void main(String[] args)
{
try
{
Class.forName("test.Static");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
}
With the following Static class being loaded:
package test;
public class Static
{
static
{
System.out.println("Static Initializer ran...");
}
}
If the static initializers are not ran until the conditions you listed are met then why does this println get executed when I run my test? That is which of your listed conditions am I meeting?
Invisible dependencies between classes is not a good idea. I suggest moving the code in static initializer block to a static method and calling it directly in the dependent class. The static initializer block can be rewritten to call the newly created static method.
If you need to statically initilize something in a Class that means there must be client classes dependent on that.
If there is one client, or let's call it a natural home for the initializing block, I think it would be cleanest to initialize it there.
For the many equal clients case, it may be a good idea to verify from these classes that the static initalization in the other class was successful. Then the coupling is documented and you are sure the class is always initialized before the first client needs it.
One solution would be to call a static method:
public class A {
static { DebugUtils.FLAG_TEST_USER = true; }
static void init() {}
}
Then invoke A.init() to force initialization.
However, doing this at all is a code smell. Consider replacing your static code with a standard constructor in a singleton object.
This question already has answers here:
What is the difference between a static and a non-static initialization code block
(9 answers)
Closed 8 years ago.
I was looking over some code the other day and I came across:
static {
...
}
Coming from C++, I had no idea why that was there. Its not an error because the code compiled fine. What is this "static" block of code?
It's a static initializer. It's executed when the class is loaded (or initialized, to be precise, but you usually don't notice the difference).
It can be thought of as a "class constructor".
Note that there are also instance initializers, which look the same, except that they don't have the static keyword. Those are run in addition to the code in the constructor when a new instance of the object is created.
It is a static initializer. It's executed when the class is loaded and a good place to put initialization of static variables.
From http://java.sun.com/docs/books/tutorial/java/javaOO/initial.html
A class can have any number of static initialization blocks, and they can appear anywhere in the class body. The runtime system guarantees that static initialization blocks are called in the order that they appear in the source code.
If you have a class with a static look-up map it could look like this
class MyClass {
static Map<Double, String> labels;
static {
labels = new HashMap<Double, String>();
labels.put(5.5, "five and a half");
labels.put(7.1, "seven point 1");
}
//...
}
It's useful since the above static field could not have been initialized using labels = .... It needs to call the put-method somehow.
It's a block of code which is executed when the class gets loaded by a classloader. It is meant to do initialization of static members of the class.
It is also possible to write non-static initializers, which look even stranger:
public class Foo {
{
// This code will be executed before every constructor
// but after the call to super()
}
Foo() {
}
}
Static block can be used to show that a program can run without main function also.
//static block
//static block is used to initlize static data member of the clas at the time of clas loading
//static block is exeuted before the main
class B
{
static
{
System.out.println("Welcome to Java");
System.exit(0);
}
}
A static block executes once in the life cycle of any program,
another property of static block is that it executes before the main method.
Static blocks are used for initializaing the code and will be executed when JVM loads the class.Refer to the below link which gives the detailed explanation.
http://www.jusfortechies.com/java/core-java/static-blocks.php
yes, static block is used for initialize the code and it will load at the time JVM start for execution.
static block is used in previous versions of java but in latest version it doesn't work.