Java - Should private instance variables be access

2020-07-06 04:19发布

问题:

I know that private instance variables are accessed through their public getters and setters method.

But when I generate constructors with the help of IDE, it initializes instance variables directly instead of initializing them through their setter methods.

Q1. So should I change the IDE generated code for constructors to initialize those instance variables through their setter methods.

Q2. If yes, then why IDE don't generate constructors code in that way?

============================= EDITED =======================================

  • I use Eclipse and Netbeans IDE

  • It's a general question. But as asked by @Lords would the answer depends on whether our constructor is public or protected or package private or private?

回答1:

You should never call a non-final method from a constructor. A class constructor is used to initialize an object, and the object is not in a consistent state until the constructor returns. If your constructor calls a non-final method which is later overridden by a subclass, you can get strange, unexpected results because the object is not fully initialized when the overridden method is called.

Consider this contrived example:

class A {
    private int x;

    public A() {
        setX(2);
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getX() {
        return x;
    }
}

class B extends A {
    private int number = 10;

    @Override        
    public void setX(int x) {
        // set x to the value of number: 10
        super.setX(number);
    }
}

public class Test {
    public static void main(String[] args) {
        B b = new B();
        // b.getX() should be 10, right?
        System.out.println("B.getX() = " + b.getX());
    }
}

The output of this program is:

B.getX() = 0

The reason is that B's number member is not initialized at the time setX is called, so its default value of 0 is used.

This article has a more thorough explanation, as does Effective Java.



回答2:

Constructors are for initialization. Initialize private instance variables directly in the constructor. Methods define an object's behavior. Behavior occurs after instantiation/initialization. Manipulate the state of your instance variables with your setter methods. That's classic OOP thinking and probably why your IDE is generating the code it does.



回答3:

That depends. If your setters/getters are simply accessing the members you should access them directly. If you also have some code along with it, use setters.



回答4:

You should decide which fields you will initialise with the constructor and which to initalise with a setter. (both is possible) I prefer to use the constructor only as much as possible and often have no setters.

This should be configurable/selectable in IDE. Without knowing your IDE there is no way to know why it works the way it does.



回答5:

Good answers. Only want to add that Eclipse (the one I use often) has templates, which you can modify in order to generate your code the way you want. It could help to adjust the code to your needs.

PS. I rather use setters and getters. Just as an habit, keeps the code coherent, I feel like it will be easier to read for someone else if I keep the habits all over the code.



回答6:

First of all initialization != setters (at least not always)

But IDEs are just playing nice with once revered JavaBean design pattern Assuming property changes should happen via setters.

So, it is a matter of design. If your classes represent pure value objects, no harm in initializing via = But if your classes have a potential of becoming a JavaBean whose property change is more than just init or assignment, go with set* calls.



回答7:

Private instance variables of a class should be (I believe need to be) declared outside of any class constructor. If I could break part of your question down into two parts:

Q1) If instance variables are initialized when a class is instantiated, unlike local variables, why bother doing the extra work within a given class constructor (?).

A1) Although you do not need to initialize instance variables (private string someString; defaults to null and is legal), one reason for doing so is that the default assigned by the compiler may not be the value you want, or worse, incorrect (which the compiler should catch).

Q2) Assuming the part above, what is the significance of get; set; properties?

A2) Aside from the fact they are easy and more elegant that a method equivalent, properties can be used at anytime within your class (obviously), they can be used as simple assignments or contain additional code (someone already stated this for validating information), and finally the data is self contained within the class and therefore easier to debug.

All this being said, you may have a perfectly valid reason for doing things differently than what a book or someone else says. There are always acceptions to the "rule(s)", and you should code accordingly.