What does the unnamed "static {}" method do in a java class? [duplicate] - java

What is this?
public class ABC {
public ABC() {
System.out.println("world");
}
static {
System.out.println("hello");
}
}
Will print:
hello
world
I don't really understand this, or what kind of method that static code is.

It's called a "static initialisation block".
It runs when the class is first loaded; only once.
For example, a constructor will run each time the class is instantiated; the static block only runs once, when it's first loaded statically by the VM/Class loader.

I think it's worth noting the static block will be run exactly once each time a classloader loads a class. This means if you have more than one classloader, the block can execute more than once.

Related

non-static main method in eclipse

I just started learning java using eclipse IDE. I noticed that main method has to be static else it throws error. Because of this I have to declare many Scanner class' objects for each user-given input. Is there a way to make the main method non-static or defining main method without the static keyword in eclipse??
Is there a way to make the main method non-static or defining main method without the static keyword [...]?
No, this is part of how java works.
There is no way around it.
But it shouldn't impact your application since you can always create an instance of your main class and call another method on it:
public class X {
public static void main(String args[]) {
new X().nonStaticMain();
}
public void nonStaticMain() {
// just pretend this is your main
}
}
The main method is the first method that JVM looks for during compilation. This main method has to be executed even before the instantiation of any object of the class. so that later these instantiated objects will invoke other required methods. And hence, static will help the main to run before object instantiation. It is not possible to run the main method without the static keyword.
The answer is no.
You can have a look at these links too:
[A Closer Look at the "Hello World!" Application]
(https://docs.oracle.com/javase/tutorial/getStarted/application/index.html)
Why is the Java main method static?

Can one force execution of the static blocks of all the files in the application?

My goal is to have several classes to have a block of code that runs at the beginning of the program. Assume for a second that classes can be added to the project on a whim, and it will be impractical to have a static function that is called in the beginning of main.
I have tried to place the initialisation routine within the static block of those classes, and it works almost as expected, but not quite. These blocks get called only after something else in that class gets called. This can be demonstrated by the code below:
Test.java
public class Test
{
public static void main(String[] args)
{
System.out.println("Begin");
new Another();
}
}
Another.java
public class Another
{
static
{
System.out.println("Another.static{}");
}
public Another()
{
System.out.println("Another.Another()");
}
}
Another2.java
public class Another2
{
static
{
System.out.println("Another2.static{}");
}
public Another2()
{
System.out.println("Another2.Another2()");
}
}
The output is:
Begin
Another.static{}
Another.Another()
It can be seen that Another2 is assumed not to be there at all.
The question is: Is it possible to "kick" all the classes to execute their static blocks if they have them?
Static blocks are executed if the class is loaded by the ClassLoader. So if you iterate over all your classes and load them via a class loader (no need to instantiate them!) every static block would get executed once.
On a deeper level I can't imagine a situation where you'd actually need this. This somehow hints to misdesigned class structures.
This is not possible, since the VM will never attempt to load a class that isn't required by the code path traversed on its own. There are some obvious and some obscure reasons why its done that way.
Rule of thumb is: If there is no dependency to a class that is reachable (through code) from the programs entry point, then that class will never be loaded. Although reachable is quite lose, e.g. a reference can be established by just knowing a class' name (e.g. from a configuration file) and accessing that class with e.g. Class.forName().
What you cannot achieve is just dropping a class into the class path and have that class automagically become an additional entry point (which executing any static code without a cause from the main (and only) entry point would classify as).
Simply you can't. Static block only called when the class loader loads them for the first time into it. No other way around to call them.
It doesn't make sense to load all keep with you to use them later. Anyways, it will be executed when you use it.

Statement surrounded by static { ... statement; } why, what for? [duplicate]

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.

Java Object Class, Constructor Chaining

Does this code get called for every object creation in Java, because every object extends Object ? Or does the JVM optimize it in some way to avoid the creation of some many Object's object in the heap.
What exactly happens in this method registerNatives().
package java.lang;
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
Static blocks are only executed once, when the class is loaded.
As explained here or here, a block that will be executed every time an object of the class is initialized can also be defined : just remove the static keyword.
It does n't matter what registerNatives(). does. What does matter here is that you have enclosed it in static block. Static Blocks loaded and run when java Class Loader loads classes. So it is guaranteed to run exactly once per JVM.
1. The question here is not about Constructor chaining, but about static.
2. static variable will be initialized when the JVM loads the class, and JVM loads the class when the class is instantiated or any static method of that class is called.
3. So this static block will run every one time the JVM loads the class.

When is the static block of a class executed?

I have 2 jars, let's call them a.jar and b.jar.
b.jar depends on a.jar.
In a.jar, I defined a class, let's call it StaticClass. In the StaticClass, I defined a static block, calling a method named "init" :
public class StaticClass {
static {
init();
}
public void static init () {
// do some initialization here
}
}
in b.jar, I have a main, so in the main, I expect that the init() method has been called, but actually not. I suspect that is because the StaticClass has not been loaded by the jvm, could anyone tell me
Is my conclusion correct?
What triggers the jvm to load a class?
How can I get the static block executed automatically?
Thanks
Yes, you are right. Static initialization blocks are run when the JVM (class loader - to be specific) loads StaticClass (which occurs the first time it is referenced in code).
You could force this method to be invoked by explicitly calling StaticClass.init() which is preferable to relying on the JVM.
You could also try using Class.forName(String) to force the JVM to load the class and invoke its static blocks.
Yes you are right, since you are not using your StaticClass it is not loaded by the vm and therefore init() is never executed.
For your second question, you probably have to go the hard way and scan all available classes and load them.
https://stackoverflow.com/a/3223019/393657
First of all class loading is different than class initialization. For anyone looking for explanation from Java Language Specification, when is static block executed - here it is.
The JLS §8.7 says that :
A static initializer declared in a class is executed when the class is initialized (§12.4.2).
So what does the initialization mean? Let's refer to JLS §12.4.2. This describes detailed initialization procedure. However point JLS §12.4.1 might be more appropriate here. It says that :
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 (§7.6), and an assert statement (§14.10) lexically nested within T (§8.1.3) is executed.
So to make the static initializer block to be executed automatically, you have to force one of those options to happen.
You are right, the easiest way is to access the class, for instance do a
StaticClass.class.newInstance();
Or something to that respect in your main method. This will ensure the class is loaded by the classloader.
The static code is executed when your class (StaticClass I guess) is referenced.
Thus, it should be executed if you create a new instance of StaticClass or if you call one of its static methods.
Static block is executed when a loaded class is initialized or referenced first. Loading class doesnt mean that class is to initialized. JVM Class Loading is separate things to concern.
Yes, the static initializer will be executed when the class is loaded. This normally occurs when you access the class in the class loading context for the first time.
in b.jar main method class should extend that StaticClass then automatically that static block and init() will be invoked
Adding some more:
static block will be executed when jvm load class.
Here in your example you can call init() method of your StaticClass by intantiating class
like
StaticClass staticClass=new StaticClass();
or
StaticClass.class.newInstance(); this is more preferebal

Categories

Resources