This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
Hi One thing I have been wondering of late is if I have a member variable and an accessor to access that member variable, when I want to access that member variable from a method in the class should I access it directly or use the accessor. After all the accessor is there to govern the way the field is accessed. Your thoughts are appreciated Thanks Kola
Accessor is 'getX ()' and 'setX(...)', isn't it? If your 'setX' - method checks for valid parameter:
you may avoid double-checking this way. But if you're sure about the parameter:
Why do an additional check? The implementation of 'setMonth' shall be hidden from USERS of the class, not from the class itself. Since the language doesn't prohibit direct access to the member in the class, you don't earn too much, if always using the 'setMonth (int)'-Method. If something goes wrong, you still have to check your code, whether you didn't assigned somewhere month directly 'month = ...' by mistake. Not every lazyness is bad. Talking about 'getMonth' seems more obvious. What could your 'getMonth ()' - Method do for you, beside 'return month'? Of course direct access is faster. I would avoid using Methods IN the class, except to avoid double checking. [ February 20, 2004: Message edited by: Stefan Wagner ]
Hi, The reason for using accessors (getters and setters) are that they are/should be foolproof. can only be used for the sending of an integer to the member x. Therefore if you initialize x to a value and then later on in your code perform a calculation on the member x and change its value you should use the "setter" method to persist this change. By doing this you only need to unit test the calculation and not the persistance of the change. Regards, Nigel Browne
Using the accessors is "more correct" if you're an OO purist. You might as well give yourself all the advantages your clients have, that is abstraction from the actual storage or derivation of a value. I had a PowerBuilder class once that ran 10x as fast with direct variable references than when calling get() but I haven't run into anything in Java that felt slow because of using get().
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
At the risk of sounding like an extreme purist, I would say that you should always use your setters and getters and never set the variable directly. From an OO perspective, directly accessing even your own variables is Wrong with a capital W. Why? Simple--methods are virtual by default in Java. This is because classes are meant to be extensible. In other words, accessing your own variables directly is perfectly acceptable in OO theory, provided you are willing to mark your class final so it cannot be extended. An example might help.
Now you go ahead and write javadoc and publish this class as part of the X Windows library for linux (hey, it could happen). Now someone comes along and decides that for their window manager they need to extend your Counter class so that every time a new count is set, an event is fired off with the new count:
Does their SpecialCounter work? Nope. They're expecting this code in SpecialCounter to run every time the count is changed, whether by the inherited increment() method, a direct call to setCount() (though it's a protected method, other subclasses and other classes in the same package can still call it), or whatever. But wait, you say, they can override the increment() method too, right? Sure--but why should they have to? The point of OO is to allow others to extend the existing functionality without having to rewrite it. If I'm overriding a method, it means that I want that method to do something more specific to my purpose than what it was doing before. Why should I have to reimplement your increment() method when all I want is the darn thing to do the same thing you wanted it to do? And what if you had 150 other methods that alter the count without using setCount()? Am I supposed to know which methods alter the count in your class and which ones don't, and override all that do? Wait a minute--I thought OO was about knowing only the API and not having to understand the details of the implementation! And there's a practical consideration too--what if you've distributed your compiled class files and javadocs, but you don't want me to have your source code, so I don't have access to it? How could I possibly know which methods alter the count in that case? You'd have to document it! Suddenly, this is way more work for both of us than just making the call to setCount(). Also, consider a slight alteration of the above code. What if I made my increment() method private? For example, I might have an anonymous inner class that's an event listener, and when that listener is triggered it calls increment(). In my version of X Windows, a Counter instance might pass this event listener all over the system so increment() could be triggered by several different parts of the system. But it's private, and you as a developer can not override it now, even if you wanted to. With this single, simple decision not to call my own setter, I've totally broken the extensibility of my class. So, if you decide to do this, please mark your class final and let everyone know up front that you broke extensibility. Also, as a side note, there are valid reasons to break extensibility, but they're decisions you should actually consider, not just do on a whim or you end up with the above situation. An earlier poster intimated that performance might be a good reason to break extensibility in this way, and I disagree, at least with the last few versions of the JVM. As far as I'm aware, the HotSpot JVMs all have knowledge of getters and setters, and they employ special optimizations to inline them into the code automatically, so you should see no performance difference at all unless some other code that's present actually has overridden one of these methods. sev