Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference in setting fields inside or outside the constructor?

Tags:

java

public class Test {
    int value = 100;
    public Test() {

    }
}

And

public class Test {
    int value;
    public Test() {
        value = 100;
    }
}

Are equivalent, right? Is there a reason why I'd prefer to do one over the other? Obviously if the constructor takes parameters that are later given to the fields is a reason:

public class Test {
    int value;
    public Test(int value) {
        this.value = value;
    }
}

Or perhaps I need to do some special calculation.

But if I don't do that, is there another good reason?

like image 539
Voldemort Avatar asked Jan 07 '14 04:01

Voldemort


1 Answers

Well it all really depends on how you plan on using this. I'm going to assume that you don't plan to make value static but it's just there for internal purposes.

Firstly lets look at the bytecode.

D:\eclipse\workspace\asdf\bin>javap -c A.class
Compiled from "A.java"
public class A {
  int value;

  public A();
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: bipush        100
       7: putfield      #12                 // Field value:I
      10: return
}

D:\eclipse\workspace\asdf\bin>javap -c B.class
Compiled from "B.java"
public class B {
  int value;

  public B();
    Code:
       0: aload_0
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0
       5: bipush        100
       7: putfield      #12                 // Field value:I
      10: return
}

D:\eclipse\workspace\asdf\bin>

Guess what? Exactly the same! Why? Because you can't USE value until you make an object by using the new keyword.

The oracle docs states that:

As you have seen, you can often provide an initial value for a field in its declaration:

public class BedAndBreakfast {
    // initialize to 10
    public static int capacity = 10;

    // initialize to false
    private boolean full = false;
} 

This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate. Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.

So now you have confirmation that the whole point of doing it in the constructor is if you are doing something complex like initializing an array otherwise feel free to do it right there when you declare the field.

If you WERE to use static then you are obviously doing two different things. It's almost like a check to see if someone has ever created an instance of this object or not. Your variable would be 0 until someone creates an object and then it would be 100 afterward.

like image 111
Sanchit Avatar answered Nov 13 '22 06:11

Sanchit