Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a constructor within another in Java

Consider:

    int a = 0;
    int b = 3;

    //Constructor 1
    public ClassName (int a) {
        this(a, b); //Error
        //new ClassName(a, b) //No error
    }

    //Constructor 2
    public ClassName (int a, int b) {
        this.a = a;
        this.b = b;
    }

First question:

I get an error saying "b should be static". Why can't I use the default value (3) for b in this way?

Second question:

In the first constructor, if I use the comment outed part, I do not get an error. Is it an acceptable usage?

like image 359
iwsnmw Avatar asked Oct 15 '15 17:10

iwsnmw


2 Answers

The use of instance variables in an explicit constructor invocation is prohibited by the JLS, Section 8.8.7.1.

An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs.

This prohibition on using the current instance explains why an explicit constructor invocation statement is deemed to occur in a static context (§8.1.3).

You referenced the instance variable b. The compiler didn't raise this error on a because it's a local variable, which shadows the instance variable a.

The "static context" may be why your IDE is suggesting to make b static, so it can be referenced. It makes sense; the ClassName part of the object isn't constructed yet. Replace that usage of b with something else, such as a static constant, or a literal int value.

To answer your other question, typing new ClassName(a, b) isn't an error because at this point, this instance has been constructed, and you're creating a separate, unrelated ClassName object.

like image 113
rgettman Avatar answered Sep 22 '22 10:09

rgettman


First question: I get an error saying "b should be static". Why can't I use the default value (3) for b in this way?

The correct way to supply a default value for b to the other constructor is this(a, 3);. You cannot refer to instance variables until after this(...). That's just one of the rules of the language.

Second question: In the first constructor if I use the comment outed part I do not get an error. Is it an acceptable usage?

new ClassName(a, b); does something different. It creates a separate instance of the class. In my humble opinion it is probably not the best thing to do. People expect new to create one instance of a class, whereas using new ClassName in the constructor creates two.

like image 42
Paul Boddington Avatar answered Sep 25 '22 10:09

Paul Boddington