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
    }

}
Ismail Sahin
  • 2,640
  • 5
  • 31
  • 58
  • 1
    Just if you want to read more: http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html – Tomas Smagurauskas Nov 25 '13 at 18:49
  • possible duplicate of [Static initializer in Java](http://stackoverflow.com/questions/335311/static-initializer-in-java) – Cruncher Nov 25 '13 at 18:53
  • I think if you see this link, may be a chance to satisfy your eagerness. http://www.jusfortechies.com/java/core-java/static-blocks.php – Piyush Nov 25 '13 at 19:33

9 Answers9

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;
rgettman
  • 176,041
  • 30
  • 275
  • 357
  • 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. – Ismail Sahin Nov 25 '13 at 18:56
  • 1
    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`. – rgettman Nov 25 '13 at 19:02
  • so can I use second a in other section of my class like functions – Ismail Sahin Nov 25 '13 at 19:04
  • It is possible to shadow your variables this way, although it's not recommended. It's a block, like a method body. – rgettman Nov 25 '13 at 19:09
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.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
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.

Thalaivar
  • 23,282
  • 5
  • 60
  • 71
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;
    }
}
Ismail Sahin
  • 2,640
  • 5
  • 31
  • 58
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.
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
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.

MadConan
  • 3,749
  • 1
  • 16
  • 27
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);
    }

    ...
}
Michael
  • 423
  • 2
  • 8
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.

Arpit
  • 953
  • 7
  • 11
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

user1339772
  • 783
  • 5
  • 19