Java initialization order issue, static vs instance fields - java

The program below prints:
my name is:null
my name is:null
Someclass static init
AFAIK when a class is first loaded static blocks and fields are always initialized first, instance blocks and fields second. Therefore variables "objectName1" and "objectName2" should be initialized first, instance variable "list" second...but the ouput obviously contradicts this theory... Can anyone explain the program behavior (I'm not looking for a critique of the design in itself btw) ?
import java.util.ArrayList;
import java.util.List;
public class Main2{
public static void main (String[] args){
SomeClass.getInstance();
}
}
class SomeClass {
private static final SomeClass instance = new SomeClass();
public static SomeClass getInstance(){
return instance;
}
static {
System.out.println ("Someclass static init");
}
private static String objectName1 ="test1";
private static String objectName2 ="test2";
#SuppressWarnings("serial")
private List<SomeObject> list=
new ArrayList<SomeObject> () { {
add (new SomeObject(objectName1));
add (new SomeObject(objectName2));
}};
}
class SomeObject {
String name;
SomeObject (String name){
this.name = name;
System.out.println ("my name is:" +name);
}
}

Static blocks are initialized in order (so you can rely on the ones above in the ones below). By creating an instance of SomeClass as your first static initializer in SomeClass, you're forcing an instance init during the static init phase.
So the logical order of execution of your code is:
Load class SomeClass, all static fields initially defaults (0, null, etc.)
Begin static inits
First static init creates instance of SomeClass
Begin instance inits for SomeClass instance, using current values for static fields (so objectName1 and objectName2 are null)
Load SomeObject class, all static fields initially default (you don't have any)
Do SomeObject static inits (you don't have any)
Create instances of SomeObject using the passed-in null values
Continue static inits of SomeClass, setting objectName1 and objectName2
To make this work as you may expect, simply put the inits for objectName1 and objectName2 above the init for instance.

As suggested moving this line:
private static final SomeClass instance = new SomeClass();
after these:
private static String objectName1 ="test1";
private static String objectName2 ="test2";
should fix the problem.

On first look I was pretty surprised about the behavior myself, but on second thought, it is quite trivial to explain:
private static final SomeClass instance = new SomeClass();
is part of the static initialization of SomeClass. As you create an instance before initialization has completed, the class is not yet completely initialized. When you replace the System.out.println(...); with something like new Exception().printStackTrace(); you get this (note that I put all classes as static nested classes into Main)
at Main$SomeObject.<init>(Main.java:37) // new Exception().printStackTrace();
at Main$SomeClass$1.<init>(Main.java:26) // add(new SomeObject(...))
at Main$SomeClass.<init>(Main.java:23) // list = new ArrayList()
at Main$SomeClass.<clinit>(Main.java:10) // instance = new SomeClass()
at Main.main(Main.java:6) // SomeClass.getInstance();
As you see, execution still is inside Main$SomeClass.<clinit> (the class initialization), hence SomeClass is not completely initialized.
As a side note: the best way to implement Singleton pattern is to avoid it completely. The second best most likely is using enum (at least it's Josh-Bloch-approved)
class enum SomeClass {
instance;
// snip
}

The first thing that executes is probably the static initializer of the instance variable. This causes the list to be initialized using the (uninitialized) objectName1 and objectName2 variables. After that, it proceeds to initialize objectName1 and objectName2.
If you move the declaration of instance to the end of SomeClass it will probably do what you're expecting.

Related

Initialization order of nested classes

I have this piece of code, and the compiler's returns with NullPointerException where I try to create BtnAct. I've read much about initialization but still haven't come across in what order inner classes are initialized. Can someone help please?
public class BaseClass{
static Myclass myClass;
public static void main(){
myClass = new MyClass;
}
}
class MyClass{
NewClass newClass;
public MyClass(){
newClass = new NewClass();
}
class BtnActn extends AbstractAction {
BtnActn() {
super("Button");
}
#Override
public void actionPerformed(ActionEvent e) {
//blabla
}
}
}
class NewClass{
JButton button;
public NewClass(){
button = new JButton(BaseClass.myClass.new BtnActn()); //NullPointer.ex here
}
}
Here is what happens:
Base class tries to create an instance of MyClass. Please notice that at that time it's not assigned to myClass yet
the new instance of MyClass tries to create an instance of NewClass. Please notice that at that time, it's not assigned to the variable newClass yet
the new instance of NewClass tries to create a new instance of JButton. For that purpose, it first needs to access BaseClass.myClass. Unfortunately, the object BaseClass.myClass is already in memory (it's in the process of being initialized at that time), but it's not assigned to the BaseClass.myClass variable yet. So it makes a NullPointerException.
So you need to separate the initialization of your Button from the initialization of myClass variable in BaseClass.
I've read much about initialization but still haven't come across in what order inner classes are initialized.
Class initialization is about the initialization of a classes static fields and execution of static initializer blocks. However, an inner class in Java is not allowed to have any static fields or static initializers. (See JLS 8.1.3.) Hence (real) class initialization for inner classes is moot. It makes no difference when it happens ... 'cos there is nothing in an inner class to initialize.
The real problem here is that while you have a static field, its actual initialization (to a non-null value) is not done during static initialization. Rather, it would happen when some part of your code explicitly calls BaseClass.main(). However, none of your code does that ... and hence myClass is going to be null when you try to use it.
Again ... I stress ... this is not an issue of how static initialization works, because your code doesn't use static initialization to initialize the field in question.

Use of a private constructor

I'm a begginer programmer for Android and I found some code over the internet and I couldn't get what this "Class not meant to be instantiated" means?! Also what's the use of it. I would be very happy if somebody could help here.
public class Settings
{
//some code
private Settings() {} // Class not meant to be instantiated
//some code
}
The constructor is private so only the class itself can create instances. There are several reasons for doing this. A couple off the top of my head...
The class is a "utility" class that only contains static methods and so instantiating it would make no sense. As the class is commented "Class not meant to be instantiated" I guess this is the most likely reason.
The class itself controls its own lifecycle and provides methods for creating instances. For example if the class is a lazy singleton it might provide a method that creates an instance when first called and return this instance on subsequent calls.
It is a private constructor. This means that outside classes cannot create new instances using the default constructor.
A little more info
All Objects in Java have a default constructor:
public MyObject() {}
That is how you can have this class:
public class MyObject{}
and still be able to call:
MyObject mObj = new MyObject();
Private Constructors
Sometimes a developer may not want this default constructor to be visible. Adding any other constructor will nullify this constructor. This can either be a declared constructor with empty parameters (with any of the visibility modifiers) or it can be a different constructor all together.
In the case above, it is likely that one of the following models is followed:
The Settings object is instantiated within the Settings class, and is where all the code is run (a common model for Java - where such a class would also contain a static main(String[] args) method).
The Settings object has other, public constructors.
The Settings object is a Singleton, whereby one static instance of the Settings Object is provided to Objects through an accessor method. For example:
public class MyObject {
private static MyObject instance;
private MyObject(){}//overrides the default constructor
public static MyObject sharedMyObject() {
if (instance == null)
instance = new MyObject();//calls the private constructor
return instance;
}
}
This inner construct
private Settings() {}
is a constructor for Settings instances. Since it is private, nobody can access it (outside of the class itself) and therefore no instances can be created.
The constructor is private so its not meant to be called by anything outside of the class
It's not a nested class, it's a constructor. A private constructor means that you can't construct instances of this class from outside, like this:
Settings s = new Settings(); //Compilation error! :(
Now, if a class can't be instantiated, what could it be for? The most likely reason for this is that the class would return instances of itself from a static method, probably as a singleton. The settings are normally global to the program, so a singleton pattern really fits here. So there would be a static method that goes kind of like this
static private TheOnlySettings = null;
static public getSettings()
{
if(TheOnlySettings == null)
TheOnlySettings = new Settings(); //Legal, since it's inside the Settings class
return TheOnlySettings;
}
See if that's indeed the case.
As other have mentioned, a class having private constructors cannot be instantiated from outside the class. A static method can be used in this case.
class Demo
{
private Demo()
{
}
static void createObjects()
{
Demo o = new Demo();
}
}
class Test
{
public static void main (String ...ar)
{
Demo.createObjects();
}
}
We can have private constructor . Below program depicts the use of private constructor with a static function
class PrivateConstructor {
private:
PrivateConstructor(){
cout << "constructor called" << endl;
}
public:
static void display() {
PrivateConstructor();
}
};
int main() {
PrivateConstructor::display();
}

Necessity of static block in Java

I found that in Java, there is a feature called static block, which includes code that is executed when a class is first loaded (I don't understand what 'loaded' means, does it mean initialized?). Is there any reason to do the initialization bit inside a static block and not in the constructor? I mean, even the constructor does the same thing, do all the necessary stuff when a class is first initialized. is there anything that the static block accomplishes which a constructor can't?
I first want to highlight one thing thing from your question:
the constructor does the same thing, do all the necessary stuff when a class is first initialized
This is incorrect. A constructor does all the initialization necessary when an instance of a class is created. No constructors execute when the class itself is first loaded into memory and initialized (unless an instance of the class happens to be created as part of the class initialization). This confusion (between initializing a class and initializing instances of the class) is probably why you are questioning the utility of static blocks.
If a class has static members that require complex initialization, a static block is the tool to use. Suppose you need a static map of some kind (the purpose is irrelevant here). You can declare it in-line like this:
public static final Map<String, String> initials = new HashMap<String, String>();
However, if you want to populate it once, you can't do that with an in-line declaration. For that, you need a static block:
public static final Map<String, String> initials = new HashMap<String, String>();
static {
initials.put("AEN", "Alfred E. Newman");
// etc.
}
If you wanted to be even more protective, you can do this:
public static final Map<String, String> initials;
static {
Map<String, String> map = new HashMap<String, String>()
map.put("AEN", "Alfred E. Newman");
// etc.
initials = Collections.unmodifiableMap(map);
}
Note that you cannot initialize initials in-line as an unmodifiable map because then you couldn't populate it! You also cannot do this in a constructor because simply calling one of the modifying methods (put, etc.) will generate an exception.
To be fair, this is not a complete answer to your question. The static block could still be eliminated by using a private static function:
public static final Map<String, String> initials = makeInitials();
private static Map<String, String> makeInitials() {
Map<String, String> map = new HashMap<String, String>()
map.put("AEN", "Alfred E. Newman");
// etc.
return Collections.unmodifiableMap(map);
}
Note, though, that this is not replacing a static block with code in a constructor as you proposed! Also, this won't work if you need to initialize several static fields in an interrelated way.
A case where a static block would be awkward to replace would be a "coordinator" class that needs to initialize several other classes exactly once, especially awkward if it involves dependency injection.
public class Coordinator {
static {
WorkerClass1.init();
WorkerClass2.init(WorkerClass1.someInitializedValue);
// etc.
}
}
Particularly if you don't want to hard-wire any dependence into WorkerClass2 on WorkerClass1, some sort of coordinator code like this is needed. This kind of stuff most definitely does not belong in a constructor.
Note that there is also something called an instance initializer block. It is an anonymous block of code that is run when each instance is created. (The syntax is just like a static block, but without the static keyword.) It is particularly useful for anonymous classes, because they cannot have named constructors. Here's a real-world example. Since (unfathomably) GZIPOutputStream does not have a constructor or any api call with which you can specify a compression level, and the default compression level is none, you need to subclass GZIPOutputStream to get any compression. You can always write an explicit subclass, but it can be more convenient to write an anonymous class:
OutputStream os = . . .;
OutputStream gzos = new GZIPOutputStream(os) {
{
// def is an inherited, protected field that does the actual compression
def = new Deflator(9, true); // maximum compression, no ZLIB header
}
};
Constructor is invoked while creating an instance of the class.
Static block is invoked when a classloader loads this class definition, so that we can initialize static members of this class.
We should not be initializing static members from constructor as they are part of class definition not object
Static initializer will run if we initialize a class, this does not require that we instantiate a class. But the constructor is run only when we make an instance of the class.
For example:
class MyClass
{
static
{
System.out.println("I am static initializer");
}
MyClass()
{
System.out.println("I am constructor");
}
static void staticMethod()
{
System.out.println("I am static method");
}
}
If we run:
MyClass.staticMethod();
Output:
I am static initializer
I am static method
We never created an instance so the constructor is not called, but static initializer is called.
If we make an instance of a class, both static initilizer and the constructor run. No surprises.
MyClass x = new MyClass();
Output:
I am static initializer
I am constructor
Note that if we run:
MyClass x;
Output: (empty)
Declaring variable x does not require MyClass to be initialized, so static initializer does not run.
The static initializer runs when the class is loaded even if you never create any objects of that type.
Not all classes are meant to be instantiated. The constructor might never be called. It might even be private.
You may wish to access static fields of the class before you run a constructor.
The static initializer only runs once when the class is loaded. The constructor is called for each object of that type you instantiate.
You can't initialize static variables with a constructor -- or at least you probably shouldn't, and it won't be particularly useful.
Especially when you're trying to initialize static constants that require significant logic to generate, that really ought to happen in a static block, not a constructor.
They're two separate things. You use a constructor to initialize one instance of a class, the static initialization block initializes static members at the time that the class is loaded.
The static block is reqly useful when you do have to do some action even if no instances is still created. As example, for initializing a static variable with non static value.
static block does different thing than constructor . Basically there sre two different concepts.
static block initializes when class load into memory , it means when JVM read u'r byte code.
Initialization can ne anything , it can be variable initialization or any thing else which should be shared by all objects of that class
whereas constructor initializes variable for that object only .
The static block is useful when you want to initialize static fields.
The static block is useful over constructors when you do have to do some action even if no instances is still created. As example, for initializing a static variable with non static value.
One way you can understand static block is;
It acts as a constructor. however, the difference between the two is
static block instantiates class or static variables while constructor is used to instantiate object variables
Consider the following class
public class Part{
String name;
static String producer;
public Part(String name){
this.name = name;
}
static {
producer = "Boeing";
}
}
objects created from this class will have producer set to Boeing but their name is different depending on the argument passed. for instance
Part engine = new Part("JetEngine");
Part Wheel = new Part("JetWheel");
Initializing static fields in the constructor is a big mistake. Yes, you can initialize static fields in the constructor. However, the static fields will reset their value every time an object is created.
public class StaticExample {
static int myStaticField;
public StaticExample(){
myStaticField = 10;
}
}
public class Solution {
public static void main(String[] args) {
StaticExample obj1 = new StaticExample();
StaticExample.myStaticField+= 80;
// this will print 90
System.out.println(StaticExample.myStaticField);
// creating new object will reset the static field
StaticExample obj2 = new StaticExample();
// this will print 10
System.out.println(StaticExample.myStaticField);
}
}
This is unexpected and unaccepted behavior for a static field. If you now change the initialization step from a constructor to a static block, you will get the correct values.
public class StaticExample {
static int myStaticField;
static {
myStaticField = 10;
}
}
public class Solution {
public static void main(String[] args) {
StaticExample obj1 = new StaticExample();
StaticExample.myStaticField+= 80;
// this will print 90
System.out.println(StaticExample.myStaticField);
// creating new object will NOT reset the static field
StaticExample obj2 = new StaticExample();
// this will print 90
System.out.println(StaticExample.myStaticField);
}
}

What is the use of a private static variable in Java?

If a variable is declared as public static varName;, then I can access it from anywhere as ClassName.varName. I am also aware that static members are shared by all instances of a class and are not reallocated in each instance.
Is declaring a variable as private static varName; any different from declaring a variable private varName;?
In both cases it cannot be accessed as ClassName.varName or as ClassInstance.varName from any other class.
Does declaring the variable as static give it other special properties?
Of course it can be accessed as ClassName.var_name, but only from inside the class in which it is defined - that's because it is defined as private.
public static or private static variables are often used for constants. For example, many people don't like to "hard-code" constants in their code; they like to make a public static or private static variable with a meaningful name and use that in their code, which should make the code more readable. (You should also make such constants final).
For example:
public class Example {
private final static String JDBC_URL = "jdbc:mysql://localhost/shopdb";
private final static String JDBC_USERNAME = "username";
private final static String JDBC_PASSWORD = "password";
public static void main(String[] args) {
Connection conn = DriverManager.getConnection(JDBC_URL,
JDBC_USERNAME, JDBC_PASSWORD);
// ...
}
}
Whether you make it public or private depends on whether you want the variables to be visible outside the class or not.
Static variables have a single value for all instances of a class.
If you were to make something like:
public class Person
{
private static int numberOfEyes;
private String name;
}
and then you wanted to change your name, that is fine, my name stays the same. If, however you wanted to change it so that you had 17 eyes then everyone in the world would also have 17 eyes.
Private static variables are useful in the same way that private instance variables are useful: they store state which is accessed only by code within the same class. The accessibility (private/public/etc) and the instance/static nature of the variable are entirely orthogonal concepts.
I would avoid thinking of static variables as being shared between "all instances" of the class - that suggests there has to be at least one instance for the state to be present. No - a static variable is associated with the type itself instead of any instances of the type.
So any time you want some state which is associated with the type rather than any particular instance, and you want to keep that state private (perhaps allowing controlled access via properties, for example) it makes sense to have a private static variable.
As an aside, I would strongly recommend that the only type of variables which you make public (or even non-private) are constants - static final variables of immutable types. Everything else should be private for the sake of separating API and implementation (amongst other things).
Well you are right public static variables are used without making an instance of the class but private static variables are not. The main difference between them and where I use the private static variables is when you need to use a variable in a static function. For the static functions you can only use static variables, so you make them private to not access them from other classes. That is the only case I use private static for.
Here is an example:
Class test {
public static String name = "AA";
private static String age;
public static void setAge(String yourAge) {
//here if the age variable is not static you will get an error that you cannot access non static variables from static procedures so you have to make it static and private to not be accessed from other classes
age = yourAge;
}
}
Is declaring a variable as private static varName; any different from
declaring a variable private varName;?
Yes, both are different. And the first one is called class variable because it holds single value for that class whereas the other one is called instance variable because it can hold different value for different instances(Objects). The first one is created only once in jvm and other one is created once per instance i.e if you have 10 instances then you will have 10 different private varName; in jvm.
Does declaring the variable as static give it other special
properties?
Yes, static variables gets some different properties than normal instance variables. I've mentioned few already and let's see some here: class variables (instance variables which are declared as static) can be accessed directly by using class name like ClassName.varName. And any object of that class can access and modify its value unlike instance variables are accessed by only its respective objects. Class variables can be used in static methods.
What is the use of a private static variable in Java?
Logically, private static variable is no different from public static variable rather the first one gives you more control. IMO, you can literally replace public static variable by private static variable with help of public static getter and setter methods.
One widely used area of private static variable is in implementation of simple Singleton pattern where you will have only single instance of that class in whole world. Here static identifier plays crucial role to make that single instance is accessible by outside world(Of course public static getter method also plays main role).
public class Singleton {
private static Singleton singletonInstance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return Singleton.singletonInstance;
}
}
Well, private static variables can be used to share data across instances of that class. While you are correct that we cannot access the private static variables using constructs like ClassName.member or ClassInstance.member but the member will always be visible from methods of that class or instances of that class. So in effect instances of that class will always be able to refer to member.
What is the use of a private static class variable?
Let's say you have a library book Class. Each time you create a new Book, you want to assign it a unique id. One way is to simply start at 0 and increment the id number. But, how do all the other books know the last created id number? Simple, save it as a static variable. Do patrons need to know that the actual internal id number is for each book? No. That information is private.
public class Book {
private static int numBooks = 0;
private int id;
public String name;
Book(String name) {
id = numBooks++;
this.name = name;
}
}
This is a contrived example, but I'm sure you can easily think of cases where you'd want all class instances to have access to common information that should be kept private from everyone else. Or even if you can't, it is good programming practice to make things as private as possible. What if you accidentally made that numBooks field public, even though Book users were not supposed to do anything with it. Then someone could change the number of Books without creating a new Book.
Very sneaky!
The private keyword will allow the use for the variable access within the class and static means we can access the variable in a static method.
You may need this cause a non-static reference variable cannot be accessible in a static method.
Another perspective :
A class and its instance are two different things at the runtime. A class info is "shared" by all the instances of that class.
The non-static class variables belong to instances and the static variable belongs to class.
Just like an instance variables can be private or public, static variables can also be private or public.
Static variables are those variables which are common for all the instances of a class..if one instance changes it.. then value of static variable would be updated for all other instances
For some people this makes more sense if they see it in a couple different languages so I wrote an example in Java, and PHP on my page where I explain some of these modifiers. You might be thinking about this incorrectly.
You should look at my examples if it doesn't make sense below. Go here http://www.siteconsortium.com/h/D0000D.php
The bottom line though is that it is pretty much exactly what it says it is. It's a static member variable that is private. For example if you wanted to create a Singleton object why would you want to make the SingletonExample.instance variable public. If you did a person who was using the class could easily overwrite the value.
That's all it is.
public class SingletonExample {
private static SingletonExample instance = null;
private static int value = 0;
private SingletonExample() {
++this.value;
}
public static SingletonExample getInstance() {
if(instance!=null)
return instance;
synchronized(SingletonExample.class) {
instance = new SingletonExample();
return instance;
}
}
public void printValue() {
System.out.print( this.value );
}
public static void main(String [] args) {
SingletonExample instance = getInstance();
instance.printValue();
instance = getInstance();
instance.printValue();
}
}
I'm new to Java, but one way I use static variables, as I'm assuming many people do, is to count the number of instances of the class. e.g.:
public Class Company {
private static int numCompanies;
public static int getNumCompanies(){
return numCompanies;
}
}
Then you can sysout:
Company.getNumCompanies();
You can also get access to numCompanies from each instance of the class (which I don't completely understand), but it won't be in a "static way". I have no idea if this is best practice or not, but it makes sense to me.
In the following example, eye is changed by PersonB, while leg stays the same. This is because a private variable makes a copy of itself to the method, so that its original value stays the same; while a private static value only has one copy for all the methods to share, so editing its value will change its original value.
public class test {
private static int eye=2;
private int leg=3;
public test (int eyes, int legs){
eye = eyes;
leg=leg;
}
public test (){
}
public void print(){
System.out.println(eye);
System.out.println(leg);
}
public static void main(String[] args){
test PersonA = new test();
test PersonB = new test(14,8);
PersonA.print();
}
}
>
14
3
When in a static method you use a variable, the variable have to be static too
as an example:
private static int a=0;
public static void testMethod() {
a=1;
}
If a variable is defined as public static it can be accessed via its class name from any class.
Usually functions are defined as public static which can be accessed just by calling the implementing class name.
A very good example of it is the sleep() method in Thread class
Thread.sleep(2500);
If a variable is defined as private static it can be accessed only within that class so no class name is needed or you can still use the class name (upto you).
The difference between private var_name and private static var_name is that private static variables can be accessed only by static methods of the class while private variables can be accessed by any method of that class(except static methods)
A very good example of it is while defining database connections or constants which require declaring variable as private static .
Another common example is
private static int numberOfCars=10;
public static int returnNumber(){
return numberOfCars;
}
*)If a variable is declared as private then it is not visible outside of the class.this is called as datahiding.
*)If a variable is declared as static then the value of the variable is same for all the instances and we no need to create an object to call that variable.we can call that variable by simply
classname.variablename;
private static variable will be shared in subclass as well. If you changed in one subclass and the other subclass will get the changed value, in which case, it may not what you expect.
public class PrivateStatic {
private static int var = 10;
public void setVar(int newVal) {
var = newVal;
}
public int getVar() {
return var;
}
public static void main(String... args) {
PrivateStatic p1 = new Sub1();
System.out.println(PrivateStatic.var);
p1.setVar(200);
PrivateStatic p2 = new Sub2();
System.out.println(p2.getVar());
}
}
class Sub1 extends PrivateStatic {
}
class Sub2 extends PrivateStatic {
}
If you use private static variables in your class, Static Inner classes in your class can reach your variables. This is perfectly good for context security.
ThreadLocal variables are typically implemented as private static.
In this way, they are not bound to the class and each thread has its own reference to its own "ThreadLocal" object.
Private static fields and private static methods can useful inside public static methods. They help to reduce the too much logic inside public static methods.

Java : in what order are static final fields initialized?

Okay, so say I have a class that looks like this :
public class SignupServlet extends HttpServlet {
private static final Logger SERVLET_LOGGER=COMPANYLog.open(SignupServlet.class);
private static final ExceptionMessageHandler handler = new ExceptionMessageHandler();
private static final SignupServletObservableAgent signupObservableAgent =
new SignupServletObservableAgent(null, SERVLET_LOGGER);
}
Can I count on the class loader to initialize those fields in order, such that I can rely on SERVLET_LOGGER to be instantiated before signupObservableAgent?
Yes, they are initialized in the order in which they appear in the source. You can read all of the gory details in The Java Language Specification, ยง12.4.2. See step 9, which reads:
... execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block, except that final class variables and fields of interfaces whose values are compile-time constants are initialized first ...
I think that initialization of static fields could be re-ordered. At least that is how I understand JMM specification
There are a number of cases in which accesses to program variables (object instance fields, class static fields, and array elements) may appear to execute in a different order than was specified by the program.
if sub class and super class is there.
EX:
'A' : super class
'B' : sub class and it extends super class 'A'
when B class loaded then A class also loads
all static variables get memory with default value from 'A' and 'B' class
then static members (static variable,static block) are executed in top to bottom order of 'A' class and then 'B' class in order they declared .
finally main method executed from sub class automatically.
Not really answering the question, but asking more here -) . Just came across an interesting example with static field initialization order. Here is the example:
public class Foo {
private static final Long result = method1();
private static String string = "something";
private static Long method1() {
if (string == null) {
throw new IllegalStateException("BOOM");
}
return 1L;
}
public static void main(String[] args) {
System.out.println("here");
}
}
This will produce IllegalStateException. I understand that the sequence here is that first we evaluate "result" field which calls method1() and bypasses "string" value initialization. "string" is meant to be a constant, but I forgot to put a "final" modifier when wrote tests. But should such cases be handled in the runtime? Meaning when we invoke "if (string == null)" should JRE to be smart enough to go and verify that "string" has not been initialized and initialize it?
This is a place where you can use a static block which would guarantee the sequence of execution.
public class SignupServlet extends HttpServlet {
private static final Logger SERVLET_LOGGER;
private static final ExceptionMessageHandler handler;
private static final SignupServletObservableAgent signupObservableAgent;
static {
SERVLET_LOGGER = COMPANYLog.open(SignupServlet.class);
handler = new ExceptionMessageHandler();
signupObservableAgent = new SignupServletObservableAgent(null, SERVLET_LOGGER);
}
}

Categories

Resources