Sign up ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free.
    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?

share|improve this question
    
You are constructing an object. You can't use the fields of an object you haven't yet constructed, hence the fact that b should static (you are using the b defined in the class). With b static, b would no longer be dependent on a specific instance. Secondly, using new ClassName(a,b) you would be creating a new instance of the same class in the constructor. It's legit, but it's not a substitute for this(a,b); It's a different thing. – Zaphod Beeblebrox 1 hour ago
    
I would be very leery of creating an extra ClassName object in a ClassName constructor. See Paul Boddington's answer for details. – azurefrog 1 hour ago
    
You're calling one function explicitly to call another. That just has no sense to it. Minimize your code, it helps things run fasteron any platform. – David Pulse 1 hour ago
    
@brso05 I was referring to the bit in PB's answer where he says "People expect new to create one instance of a class, whereas using new ClassName in the constructor creates two.", regarding question 2. – azurefrog 1 hour ago
    
@DavidPulse while this example isn't practical there are practical applications for this technique... – brso05 1 hour ago

3 Answers 3

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.

share|improve this answer

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.

share|improve this answer

When using variables in classes, it is important to note where that validity of scope is. You've instantiated new a,b variants of the variables there. You're tricking yourself into believing those are the same variables. Actually they're in another address space. If you want to use your class variables you'll have to take out the parameters to the functions. Then they'll sync with the class you're in, rather than isolating the arguments a, b to within the scope of your function,

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.