views:

128

answers:

7

I always wonder about the best way to access a class attribute from a class method in Java.

Could you quickly convince me about which one of the 3 solutions below (or a totally different one :P) is a good practice?

public class Test {

    String a;


    public String getA(){
        return this.a;
    }

    public setA(String a){
        this.a = a;
    }

    // Using Getter
    public void display(){

        // Solution 1
        System.out.println(this.a);

        // Solution 2
        System.out.println(getA());

        // Solution 3
        System.out.println(this.getA());
    }


    // Using Setter
    public void myMethod(String b, String c){

        // Solution 1
        this.a = b + c;

        // Solution 2
        setA(b + c);

        // Solution 3
        this.setA(b + c);
    }
}
A: 

Using getters and setters is the way to go.

  • It's commonly accepted practise

So other programmers are more likely to understand your code.

  • It gives the class author options in the future

Say you want to prevent someone setting a to null. Expose the member and you can never do it.

As for whether to use this - I try to use this consistently to make it very clear to anyone else which are instance members and which are local variables at any point - also helps avoid accidental shadowing, but I think this is less important and more a style thing.

Also - this.a is an instance member (one per instance) not a class member (one-per-class, would be static). Another reason to use this to be clear.

Brabster
+2  A: 

If you need to create any validation in the future you'll want a setter/getter . When you make a variable visible you brake the class encapsulation. In theory it means that your code is not so Object Oriented :P , but in practice you lose the ability to do a lot of code refactorings. For example, extracting a interface. And for the this call, I think its redundant, but that's just me :)

Lucass
The question is not about making variables visible, it is about how best to access member variables from within the class itself, i.e. access directly or use the getters and setters.
DaveJohnston
The best way to access the variables from the class itself is by accessing them directly. If you need access to a variable and solve that by creating public setters/getters then you ARE exposing internal implementation! Congratulations! Now you have locked yourself out. You cannot change the internal structure any longer because it is exposed and other classes depend on the accessor methods.
bitc
A: 

I would go with

System.out.println(getA());

and

setA(b + c);

for the simple reason that if you wanted to generally change the way an attribute is accessed or enforce any constraints as to what you could set a variable to, you can just change the getA or setA methods.

I don't like using this unless I need to explicitly distinguish between variables of the same name.

Jimmeh
A: 

I use getters and setters in a class if there is more logic involved that just returning this.value. This way I avoid duplication. An example:

...
public List<String> getList() {

    if (this.list == null) {
        this.list = new LinkedList<String>();
    }

return this.list;

}

public int getListSize() {
    return getList().size();
}
...

I always use "this" because it makes it easier for other people to read my code. There is no doubt that this.value is a class attribute, whereas value can be both a local variable and a class attribute.

das_weezul
Lazy loading shouldn't be a concern for the class itself. If it is, then I'd rather move the loading to the class' constructor.
BalusC
I just needed an example getter function doing more than returning ;o) Just out of curiosity: How would you use lazy loading? By a setter from the outside?
das_weezul
*Note: you can use `@nickname` in comments to notify commenters about replies on comments.* If loading is only a concern for callers *outside* the class, then I would just keep the lazy loading as is and get rid of `getListSize()`. If you ever need to call `getList()` from **inside** the class, then I'd rather move the loading to the class' constructor and access `this.list` instead.
BalusC
+2  A: 

That entirely depends on what the getters and setters are doing. If they do more than just getting and setting the value (which should be explicitly documented in the method's Javadoc), then it would really make difference what way you'd choose from inside the class. But if they are pure Javabean like getters/setters, then I'd rather access the variable directly by either a or this.a depending on whether there's a local variable in the scope with exactly that name.

Personally I would just keep the getters and setters "pure" according the Javabean spec and add another getter or setter with a self-explaining method name whenever I'd like to do something more than just getting/setting the value. E.g. getAndIncrement(), getAsString(), setAsInt(String), etc.

Matter of taste. It won't really harm as long as you're consistent with it throughout your coding.

BalusC
A: 

Solution 2 or 3 are best practice as they provide encapsulation to the field. For example, what if the field 'a' is a user's postcode and your application has a new requirement to always return the postcode as uppercase. With solutions 2 or 3 this becomes trivial. E.g.

private String postcode;
public String getPostcode()
{
   return postcode;
}

becomes

private String postcode;
public String getPostcode()
{
   return postcode != null? postcode.toUppercase() : null;
}

and you will only have made the change in one place instead of anywhere where the field is accessed. The addition of this is purely up to your own personal style or project standards. Personally, I don't like it as it is unnecessary and just gets in the way of readability, but for others it makes the owner of method/field clearer.

Chris Knight
And why make getPostcode() public? The variable was private, was it not? So now you have contradicted yourself and broken the encapsulation by exposing the internal implementation.
bitc
Fair enough. I misread the OP's code where `a` is default and not public.
Chris Knight
A: 

Using setA(b + c) is silly.

Getters and setters are part of the interface. Methods already have full access to the state. Be frank about it.

If you're worried that you might break an invariant then your class is too complex for you. (Admit it and refactor.)

bitc
How about being worried that you might need to change the way something's set later? And maybe forgetting to change how it's done in one of the 20 times you did it yourself before?If setting the variable is more complex than "a = (stuff)", refactoring would end up getting you a setA() ANYWAY.
cHao
You are not clear about the distinction between what's interface and what's internal access. setA() is what the outer world can see, it is not interchangeable with 'a' on any arbitrary basis. Just because both happen to have an A in their names does not make them the same. That's what you fail to understand. If it is 'a' you want to set then do so directly. If it is the interface property THEN call setA(). Now read my original answer again.
bitc
There *isn't* a difference, if you care about your objects' integrity. If setting 'a' involves more than just setting 'a' (ie: other stuff needs to be set as well when you set it), then you're asking for trouble by setting it whenever you feel like it. Even if you're really really careful and set it correctly every time, the first time you decide it should be set a little differently (say, logging when and where it's changed), you'll have to change your code in every place where you set it yourself.BTW, if "setA(x)" doesn't set a to x, then you need to pick better names for your setters.
cHao
There is a difference because you do not want to expose the implementation of the class. By creating a public setter for the internal property 'a' you've just blown it. Now you can't change your implementation because the world might depend on access to 'a'.
bitc