3

I have been working on some of my AP cs projects and came to the wonder the difference between doing this:

public class CalculateTaxes {
private Scanner in; 

public CalculateTaxes(){
    in = new Scanner(System.in);
}

}

and this:

public class CalculateTaxes {
 private Scanner in = new Scanner(System.in); 

 public CalculateTaxes(){

 }

}

I've seen many examples were they declare an object in one line and instantiate it somewhere else in the code. Why not just declare and instantiate an object in the same line?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • 3
    At the byte code level, they are *exactly* the same. So, I guess, it really depends on preference (in some cases) but for example if the constructor throws an `Exception` of some sort, you would need to initialize it in the constructor using a try and catch. – Josh M Oct 18 '13 at 16:27
  • In this scenario, the code is the same imho. However, you may have different constructors. One may initialize `in` where no parameter is passed to the constructor. Another may be `CalculateTaxes(String otherDevice)` where you don't want input to be taken from the keyboard. – bbalchev Oct 18 '13 at 16:29
  • 1
    this maybe helpful - http://stackoverflow.com/questions/4916735/default-constructor-vs-inline-field-initialization – csn Oct 18 '13 at 16:31

3 Answers3

2

Lets test how these classes will be compiled.

public class Test1 {
    private Scanner in;

    public Test1() {
        in = new Scanner(System.in);
    }
}

and

public class Test2 {
    private Scanner in = new Scanner(System.in);

    public Test2() {

    }
}

If we use javap -c Test1 we will see

Compiled from "Test1.java"
public class Test1 {
  public Test1();
    Code:
       0: aload_0       
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: new           #12                 // class java/util/Scanner
       8: dup           
       9: getstatic     #14                 // Field java/lang/System.in:Ljava/io/InputStream;
      12: invokespecial #19                 // Method java/util/Scanner."<init>":(Ljava/io/InputStream;)V
      15: putfield      #22                 // Field in:Ljava/util/Scanner;
      18: return        
}

and if we use it on Test2 we will get

Compiled from "Test2.java"
public class Test2 {
  public Test2();
    Code:
       0: aload_0       
       1: invokespecial #10                 // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: new           #12                 // class java/util/Scanner
       8: dup           
       9: getstatic     #14                 // Field java/lang/System.in:Ljava/io/InputStream;
      12: invokespecial #19                 // Method java/util/Scanner."<init>":(Ljava/io/InputStream;)V
      15: putfield      #22                 // Field in:Ljava/util/Scanner;
      18: return        
}

So as you can see the initialization of in field in Test2 class was automatically moved by compiler at start of constructor.

In fact this code will be moved at start of each constructor of that class (right after super() call if any) so only difference is that if you have few constructors you can initialize in field in one place outside constructors instead of doing it in every one of them.

But if lets say you want to initialize field depending on some argument passed in constructor then you have to do it in constructors block.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
0

If you intend to assign an object a value in one scope but need it to be visible in another it can be useful to split up the declaration and the assignment.

Pseudocode:

{ 
  // Outer loop
  SomeObject a;
  if (condition_one == condition_two)
      a = new SomeObject(4);
  else
      a = new SomeObject(12);
  a.doStuff();
}

If a had been declared only inside of the if statements, it wouldn't be visible outside of that loop.

{
  if (a == b)
      SomeObject a = new SomeObject(5);
  a.doStuff(); // ERROR
}
BlackVegetable
  • 12,594
  • 8
  • 50
  • 82
0

There's not much difference in this case. In some cases, you use different parameters depending on what parameters are sent in the constructor.

Ultimately, in a professional programming environment, your goal is not what is best "right now", but what will help you understand what's going on in 6 months when you need to reread your code and understand WHY you were doing something. HOW you implemented it will help document the intent.

PaulProgrammer
  • 16,175
  • 4
  • 39
  • 56