What does
static{
//something
}
declared inside a class definition body mean?
public class A extends B{
static {
C.register(new C(A.class,
(byte) D.x.getCode()) {
public DataSerializable newInstance() {
return new A();
}
}
);
}
}
The static block is called a "static initialization block." It is very similar to a regular constructor except that it can only initialize static variables.
I have found it to be useful when initialization of some static variable may throw an exception that you would like to handle or at least log. It is especially useful in the initialization of static final variables.
You may read more about static initialization blocks here: Initializing Fields
It executes a block of code without requiring an instance of this class, i.e. as soon as the class loader loads the class.
That becomes a static initialisation block, which can be written as a static method.
It's a static initializer. It's run once the class is loaded and it's results can be stored in static members. It's used to initialize static members that require more than the regular new Xyz() (like Lists or Maps)...
It's a static initializer. It lets you specify things that happen at the time that the class is loaded, before any instance is created.
If an exception is thrown from a static initializer it's very confusing, it's hard to tell where it came from. Anything that you do in a static initializer should have a try-catch around it and have the exception get logged. It's a good language feature to avoid if you can.
It means that you will have this section which is inside the static block extecuted FIRST on load of the class into the JVM.
Execute the following simple program might make things clearer
public class Test123 {
static{
System.out.println("Hello from static block");
}
public static void main(String[] args) {
System.out.println("In main");
}
}
The output to the above will be
Hello from static block
In main
Related
I have to work with a bunch of static legacy classes that contain static blocks.
The classes itself are only helper classes with only static methods.
Example:
public abstract class Legacy {
protected static final String[] ARRAY;
static {
//init that ARRAY
}
public static String convert(String value) {
//makes use of the ARRAY variable
}
}
Important: I don't have control over the sources and thus cannot modify the code. I know that this is a serious design flaw in how the class is build.
Problem: when accessing the class concurrently, I get exceptions from the legacy classes if the class is not initialized yet. So I have to ensure at application startup that each static class was initialized properly before.
But how could I do this?
I tried as follows:
Legacy.class.newInstance();
But that results in the following error:
java.lang.InstantiationException
at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
So probably I'm doing it wrong?
Static initializers are thread safe in that they will only be run, and by a single thread.
They may run multiple times if the class is loaded by more than one classloader, but in that case they are effectively initializing a different class.
It is therefore unlikely that the problem you are seeing is due to incomplete initialization.
It seems more likely that your convert method is doing something that is not thread safe such as modifying the array.
If you call only static methods of the legacy classes there is no need to create an instance. The static block will be executed only once (the JVM will take care of it).
See this small example.
class Legacy {
static {
System.out.println("static initializer of Legacy");
}
public static void doSomething() {
System.out.println("Legacy.doSomething()");
}
}
class LegacyDemo {
public static void main(String[] args) {
Legacy.doSomething();
}
}
If you run LegacyDemo it will print
static initializer of Legacy
Legacy.doSomething()
I need to load some classes along with their respective static initializations, for example, in a factory method implementation.
If I just make reference to the class using the below syntax, the JVM does not run the static initialization part. Actually, does the JVM even load the classes?
Class<Shape> shapeClass = Shape.class;
or
Shape s = null;
But with class.forname() it does execute static initializations.
Class.forname("Shape");
The question is if this is the only way to do load a java class along with static initializations? Or are there other ways? Any significant performance penalties for using class.forname()?
From Class.forName(String className) API: Invoking this method is equivalent to: Class.forName(className, true, currentLoader).
The second argument = true means initialize class, and initialize class means run static initializers
This is a test to check
package test;
class Test2 {
static {
System.out.println("static init");
}
}
public class Test1 {
public static void main(String[] args) throws Exception {
Class.forName("test.Test2");
}
}
output
static init
but if you load Test2 with
Class.forName("test.Test2", false, ClassLoader.getSystemClassLoader());
there will be no output. You can also use this test to see that Test.class.getName() does not load the class either.
The simplest way to make it load is to add an empty static method and call it:
class Test2 {
public static void load() {
}
...
Test2.load();
When you load/resolve a class, the static initializers are executed in the order they are defined. It shouldn't matter how you load them, reflection or not. That is, unless you're meaning some other sort of initialization?
I have a utility class that looks like this:
public final class MyUtils {
public static final List<String> MY_VALUES = new ArrayList<String>();
{
MY_VALUES.add("foo");
MY_VALUES.add("bar");
}
}
I call this from another class just like this:
MyUtils.MY_VALUES
If I do so, the list is empty and if I debug I see the static block is never run.
As I understand from the answers to When does static class initialization happen? and How to force a class to be initialised? the block should run when a static field of the class is assigned, which I do right away. I also tried making the variable non-final to fulfill the condition "a non-constant static field is used".
I could use an init method as also sugested in the two other questions and als in Why doesn't my static block of code execute? but I would still like to understand why it isn't working in the first place although I seem to have fulfilled the conditions from the language specification.
You have to add the static keyword in front of your block in order to make it static:
public final class MyUtils {
public static final List<String> MY_VALUES = new ArrayList<String>();
static {
MY_VALUES.add("foo");
MY_VALUES.add("bar");
}
}
A initialization block gets called everytime the class is constructed.
A static initialization block gets called only once at the start of your program.
import java.util.*;
import net.rim.vm.*;
public class AddressBook {
static Vector addresses;
static PersistentObject persist;
static {
// Hash of "net.rim.sample.AddressBook".
long KEY = 0xa3b3159378f59a29L;
persist = PersistentStore.getPersistentObject( KEY );
if( persist.getContents() == null ) {
persist.setContents( new Vector() );
persist.commit();
}
addresses = (Vector)persist.getContents();
}
}
void add( Address a ) {
addresses.addElement( a );
persist.commit();
}
}
Source
This class is loaded
The static instance variables are initialized
static Vector addresses;
static PersistentObject persist;
Then the static block is executed.
static{....}
A static block initializer is executed when the class is first loaded by the ClassLoader. This happens the first time an object of that class is instantiated, or the first time a static member of that class is accessed.
A static block initializer can be tought of as a constructor for instance fields. A constructor initializes instance variables with proper values, where the static block initializer assigns proper values to static variables.
Static blocks are useful when you want to initialize your static fields by executing code, like function invocation and loops, which cannot be place in a simple assignment statement.
This static {....} is called as static blocks. Those are used to initialize your static members. When class is loaded/intialized, static block is executed.
In your example, you are initializing address and vector using static block.
That is a Static Initializer, assuming you have only one class loader it will make sure that that code will be executed just once (or N times for N class loaders).
Static initializers are usually used to initialize fields for Singleton objects.
The static block will be executed when this class's (AddressBook) is first loaded in to the JVM.
Your variables will be available for use after the program is loaded.
These static variables can be used without creating the objects for the class
static Vector addresses;
static PersistentObject persist;
And if we use something like static{---}. It is called as Static Initializers. It is initialized before creating the objects
The static variables are initialized firstly, then the static block
i'm currently just fooling around with different classes to test how they work together, but im getting an error message in NetBeans that i cant solve. Here's my code:
class first_class.java
public class first_class {
private second_class state;
int test_tal=2;
public void test (int n) {
if (n>2) {
System.out.println("HELLO");
}
else {
System.out.println("GOODBYE");
}
}
public static void main(String[] args) {
state.john();
TestingFunStuff.test(2);
}
}
class second_class
public class second_class {
first_class state;
public int john () {
if (state.test_tal==2) {
return 4;
}
else {
return 5;
}
}
}
Apparently i can't run the method "john" in my main class, because "non static variable state cannot be referenced from a static context" and the method "test" because "non static method test(int) cannot be referenced from a static context".
What does this mean exactly?
Screenshot of the error shown in netbeans: http://imageshack.us/photo/my-images/26/funstufffirstclassnetbe.png/
It means state must be declared as a static member if you're going to use it from a static method, or you need an instance of first_class from which you can access a non-static member. In the latter case, you'll need to provide a getter method (or make it public, but ew).
Also, you don't instantiate an instance of second_class, so after it compiles, you'll get a NullPointerException: static or not, there needs to be an instance to access an instance method.
I might recommend following Java naming conventions, use camelCase instead of under_scores, and start class names with upper-case letters.
The trick here to get rid of the error message is to move the heavy work outside of main. Let's assume that both lines are part of a setup routine.
state.john();
TestingFunStuff.test(2);
We could create a function called setup which contains the two lines.
public void setup() {
state.john();
TestingFunStuff.test(2);
}
Now the main routine can call setup instead, and the error is gone.
public static void main(String[] args) {
setup();
}
However, the other members are correct in that your instantiation needs some cleanup as well. If you are new to objects and getting them to work together might I recommend the Head First Java book. Good first read (note first not reference) and not all that expensive.
Classes can have two types of members by initialization: static and dynamic (default). This controls the time the member is allocated.
Static is allocated at class declaration time, so is always available, cannot be inherited/overridden, etc. Dynamic is allocated at class instantiation time, so you have to new your class if you want to access such members...
It is like BSS vs heap (malloc'd) memory in C, if that helps..