3

I applied a job and they gave me a java test. There were many unknown concepts that I'm not familiar with, and have newer seen as well. One is about static field. I'm posting one of the strangest question below and asking for help.

The code includes the question in comments.

public class MyClass {

    //what is the purpose of section, I mean for which purpose is it being used?
    //can variables inside of belove section be used or not. If can be used, then how?
    static{ 
        int a=5;
        double x=4.1;
    }

    //why this does not give any error because of redecleration of integer a?
    static int a=4;

    public static void main(String[] args) {
        System.out.println(a+"");//the output is 4
    }

}
3

9 Answers 9

5

This block

static{ 
    int a=5;
    double x=4.1;
}

is known as a static initializer. It is used to initialize static fields when more than one statement may be necessary to initialize a field.

But here, you're not actually initializing any static variables. You just declared two local variables.

This is the line that counts:

static int a=4;
Sign up to request clarification or add additional context in comments.

4 Comments

forgive me but I did not understand "It is used to initialize static fields when more than one statement may be necessary to initialize a field" could you explain a little bit more.
You can always say static int a = 4; -- declaration and initialization all in one line. Static initializers are used when multiple statements are necessary to come up with a value to initialize the static variable. Contrived example: { int x = 5; int y = 4; a = x * y; } That statement uses multiple statements to initialize the static variable a to 20.
so can I use second a in other section of my class like functions
It is possible to shadow your variables this way, although it's not recommended. It's a block, like a method body.
3

Your static block opens a new scope:

static{ 
    int a=5;
    double x=4.1;
}

Inside this scope, a and x are created as local vairables, and once the scope ends, they disappear, just like with any other scope, static or not.

This is why it does not conflict with the static member 'a', which is initialized to 4, resulting in that value being printed out.

Comments

2

It's a static initializer. It's executed when the class is loaded. You can think of it as class constructor.

static{ 
        int a=5;
        double x=4.1;
}

why this does not give any error because of redecleration of integer a?

static int a=4;

There are two local variables and they don't conflict as 'a' is inside the 'static' block. and the other variable 'a' is in class level.

Comments

2

this is not an answer just tested what I understand from the answer playing with code I got below results

public class MyClass {

    static int a=6;
    static double x=6.1;

    static{ 
        int a=5;
        double x=4.1;
        initialize(a, x);
    }

    public static void main(String[] args) {
        System.out.println("value of a = "+a);//the output is value of a = 5
        System.out.println("value of x = "+x);//the output is value of x = 4.1
    }

    static void initialize(int a1, double x1){
        a=a1;
        x=x1;
    }
}

another shot

public class MyClass {

    static{ 
        int a=5;
        double x=4.1;
        initialize(a, x);
    }

    static int a=6;
    static double x=6.1;

    public static void main(String[] args) {
        System.out.println("value of a = "+a);//the output is value of a = 6
        System.out.println("value of x = "+x);//the output is value of x = 6.1
    }

    static void initialize(int a1, double x1){
        a=a1;
        x=x1;
    }
}

Comments

1

There are two questions, so you'll get two answers.

  1. It's called static initializer block, it will be copied to every constructor, those variables are local to the block, you could use them within that block to initialize something but they should be constants probably in that case.
  2. Two reasons, it's not local to that block. And one would shadow the other if there was a sub-block.

Comments

1

The block

 static{

 }

is called a static initializer. It is intended to work like a constructor for a Class instance (NOT an Object instance). The reason the static line does not give any error is because the variables declared and initialized in the static block are only scoped to that block. Once the block has completed execution, those variables go out of scope and no longer apply. The line

 static int a=4;

however is Class scoped, so it refers to a completely different variable despite having the same name, in much the same way that the two variables with the same name for the following code refer to two different variables:

 public MyObject{
   private int value;

   public MyObject(int value){
     this.value = value;  // "this" means this instance and removes any ambiguity 
                          // for the compiler
   }
 }

In both cases, the scope of the variables are different and the compiler treats them as two distinct variables.

Comments

1

The static block can be used to initialize objects that you normally wouldn't in its constructor, and almost never for primitives:

public class Foo {

    static Bar soap = new Bar();
    static {
        soap.doSomething();
        soap.removeSuds();
        Bar.doSomethingElse(soap);
    }

    ...
}

Comments

1
static { 
    int a=5;
    double x=4.1;
}

The purpose of the above block is make the code inside it execute before the main() method does.

Whenever one open's a block in java and declare something inside it, here a static block with variables a and x, become local to that particular block, i.e. a and x can't be accessed outside the static block.


For more info on scope and lifetime of variables in java refer to following links:

http://www.cs.umd.edu/~clin/MoreJava/Objects/local.html
http://www.c4learn.com/java/java-variable-scope/

So, the static block in this code is there to just confuse you, it does not have any impact on the execution or result of the program in your case.

After the execution of static block, we've moved out of it thus destroying it's local resources, i.e. a and x. Now, according to Java, there doesn't exist any variable named a, a new variable with the same name can be initialized.

@ismail - In Java, all code is executed from top-to-bottom order like any other language. Assuming you that all static blocks are executed before main() method is called. So consider a case where you have two static blocks:

public class MyClass {
    static {
        System.out.println("Static Block 1");
    }
    static {
        System.out.println("Static Block 2");
    }
}

The output of above code would be
Static Block 1
Static Block 2

Something similar is done by you in the your 1st code. 1. You declared some static instance variables. 2. You created a static block with some local variable and called a function from that block which could manipulate instance variables. 3. Due to the flow of Java, firstly instance variables were created and then they were manipulated by your static block. That's how you received modified output.

But in 2nd code, the static instance variables got initialized after the execution of static block, hence you received initial values in the output.

Comments

0
 static{ 
        int a=5;
        double x=4.1;
    }

declares two LOCAL variables a and x and these are not available beyond the static block.

static int a=4; 

is declared at class level and can be used by all methods in the class.

System.out.println(a+""); 

looks for variable a at class level and prints 4

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.