15

I am a little bit confused about the following piece of code:

public class Test{

  int x = giveH();
  int h = 29;

  public int giveH(){
     return h;
  }

  public static void main(String args[])
  {
      Test t = new Test();
      System.out.print(t.x + " ");
      System.out.print(t.h);          
  }
}

The output here is 0 29, but I thought that this has to be a compiler error, because the variable h should have not been initialized when it comes to the method giveH(). So, does the compilation go through the lines from top to bottom? Why is this working? Why is the value of x 0 and not 29?

abligh
  • 24,573
  • 4
  • 47
  • 84
bucky
  • 392
  • 4
  • 18
  • 1
    it's because of the order in which things are done. 1/ declaration of things 2/ definition if required. Consider it like this: `int h; int x; x = giveH(); h = 29;` – njzk2 Nov 12 '15 at 18:37

6 Answers6

21

The default value of int is 0 (see here). Because you initialize x before h, giveH will return the default value for a int (eg 0).

If you switch the order like this

int h = 29;
int x = giveH();

the output will be

29 29
ThomasThiebaud
  • 11,331
  • 6
  • 54
  • 77
  • 1
    yeah, but giveH() returns the value of h, so the methods knows about "h"...and h were initialized with a value of 29..so im not sure that i get it. – bucky Nov 12 '15 at 10:29
  • 5
    The method knows about h, but not about his value. When you called `giveH()`, `h` was not initialized so his value was `0` (not 29, order matters). `giveH()` is just called once, when you initialize your variable. – ThomasThiebaud Nov 12 '15 at 11:40
  • 1
    One should distinct the variable declaration, which is the fact of saying "my variable `h` is a `int`", and the variable definition, which is the fact of saying "my integer `h` has a value of `29`". When your variable `x` is initialized, it calls the method `giveH()`, which retrieves the value of `h`. At this point, since the initialization of `h` comes after `x`, the variable `h` is only declared (otherwise the code would not compile). By default, the `int` variables are given a value of `0` until its value gets declared. That's why you get `0` from `giveH()`, and not `29` nor a compile error – dounyy Nov 12 '15 at 12:57
  • I hadn't thought of that, very nice, +1. I've also never come across it before - setting instance variables to be the result of an instance method is somewhat unusual. – NickJ Nov 12 '15 at 15:59
  • It probably should be noted that the reason this happens is because initializing x happens only once. So the value of x is equal to the value of h **at the time of the class's initialization**. It is a common misconception of new developers to believe that setting a variable to the result of a method makes the variable's value equal to the result of the method at any given point in execution. This is false. – nukeforum Nov 12 '15 at 16:40
4

Compilation in Java doesn't need the method to be declared before it is used. The Java tutorial goes into a bit more detail on initialization.

Here's a way to think about it: the compiler will make a note to look for a method called giveH somewhere in scope, and it will only error if it leaves the scope and doesn't find it. Once it gets to the giveH declaration then the note is resolved and everyone is happy.

Also, the variable initialization for instance variables in Java is moved to the beginning of the constructor. You can think of the lines above being split into two parts, with the declaration for x and h above, and the assignment inside the constructor.

The order of declaration does matter in this case. When the variable x is initialized, h has the default value of 0, so giveH() will return that default value. After that, the variable h is given the value 29.

You can also look at the Java Language Specification sections on Field Initialization and Forward References During Field Initialization.

Scott M.
  • 7,313
  • 30
  • 39
  • ok, thanks..but when the ordering is irrelevant, why x got the value of 0 and not 29? cause the method giveH() "knows" that there is a instance variable named "h", because the method returns its value..so i don't understand why it returns 0. – bucky Nov 12 '15 at 10:27
  • OK I think that was actually an incorrect statement. The ordering does matter. I'll edit to make that clear. – Scott M. Nov 12 '15 at 10:30
3

@Maloubobola has provided the correct answer, but since you don't seem to fully understand yet, let me try to elaborate.

When Test is created, it runs the variable initialization (x = giveH(), h= 29) once. Your misunderstanding may be that variable x is always determined by giveH(), whereas it only determines it's value when x is initialized.

That's why the order of the statements is crucial here; x is initialized before h, and therefore h is 0 when giveH() is called at x's initialization.

Jochem Kleine
  • 186
  • 1
  • 10
2

It's bad practice to use a method in the field initializer. You can fix this by making h final. Then it will be initialized when the class is loaded.

import java.util.ArrayList;

public class Test {
    int x = giveH();
    final int h=29;

    final public int giveH(){
        return h;
    }

    public static void main(String args[]) {
        Test t = new Test();
        System.out.print(t.x + " ");
        System.out.print(t.h);          
    }
}
ThomasThiebaud
  • 11,331
  • 6
  • 54
  • 77
user2872645
  • 21
  • 1
  • 3
1

If we do not initialize the value for non static variables like x in this program JVM will provide default value zero for class level non static variables.

Preethi
  • 11
  • 1
0

Once declared, all the array elements store their default values. Elements in an array that store objects default to null. Elements of an array that store primitive data types store: 0 for integer types (byte, short, int,long); 0.0 for decimal types (float and double); false for boolean; \u0000 for char data.

Actauls values will come only when we give initialize them