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);
}
}
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.
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 :)
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.
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.
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.)
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.
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.
Related
This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 7 years ago.
Why do we exactly need to use the set and get methods in our class that use private attributes?
When it is really used during our program process?
Can we still make it work without it (without changing the private attributes to public)?
This is an example of a source code when we are using the set and get methods:
public class Dog {
private String dogName;
private int dogAge;
public Dog(String dogName, int dogAge) {
this.dogName = dogName;
this.dogAge = dogAge;
}
public String getDogName() {
return dogName;
}
public void setDogName(String dogName) {
this.dogName = dogName;
}
public int getDogAge() {
return dogAge;
}
public void setDogAge(int dogAge) {
this.dogAge = dogAge;
}
#Override
public String toString() {
return "Dog{" + "dogName=" + dogName + ", dogAge=" + dogAge + '}';
}
}
Why do we exactly need to use the set and get methods in our class
that use private attributes?
If you want to hide details of implementation (encapsulation - a fundamental principle of object-oriented programming), you don't want someone from outside to access them, you only supply a method that returns some value, but you don't want to reveal implementation.
Also sometimes when you set a value, you need to change other variables that might be related, or changing some logic, it's not always a simple assignment statement.
When it is really used during our program process?
It's very hard to answer this question, it really depends on the program. You use setters and getters when you want to.. get, or set a value.
Can we still make it work without it?
Sure, it works when you have public fields instead of privates, in sense of design, it's recommended to start with private variables always, and change them only when you must.
If you don't see the point of encapsulation, allow me to demonstrate with a "real life" example (which .
private boolean amIDrunk = true;
public boolean getAmIDrunk(Object asker){
if (asker instanceof PoliceOfficer){
return false;
} else if (asker instanceof DrinkingBuddy ){
return true;
}
return amIDrunk;
}
public void setAmIDrunk(boolean setter){
if (hadLessThen10Beers()) {
this.amIDrunk = false;
return;
}
this.amIDrunk = setter;
}
Sure, this is a 'nitwit' example, but it's just to show that sometimes, just because you call a setter, there might be a reason not to set that value, and sometimes, when a getter is called, there might be a reason, you don't want to return the actual value.
Anyway, to continue in this example: having amIDrunk as a private variable, makes sure someone else doesn't declare you as 'drunk' by setting amIDrunk to true, without the implementation of your own set method to agree with it.
I personally don't like the setters and getters and replace them with public fields if I can. However, there are techical reasons to keep them:
Mocking: Mocking frameworks such as Mockito or Easymock cannot mock or override direct field accesses
Proxies: For various reasons, proxies are used (Scopin in DI frameworks, logging, etc). Again, does not work with fields
JavaBeans based frameworks: Some frameworks for XML serialization don't support field access.
So, in many cases using the getters/setters just makes your life easier. However, if you are in charge of all code depending on your classes, just use Refactor->Encapsulate Field in eclipse (quite sure similar functionality exists in all major IDEs) as soon as you run into problems.
I recommend to read about Kotlin kotlinlang.org
You can write getters/setters for POJO in 1 line:
e.g.
data class Customer(val name: String, val email: String, val company: String)
Another reason for using 'access methods' (setters and getters) is that it is a convention used in IoC (inversion of control). So frameworks like Spring etc.
It may seem tedious to create them, but if you're using eclipse as an IDE for example you can generate setters and getters automatically (source|generate getters and setters).
Further your private member variables are important.
Let's say you have :
public String telephoneNumber;
What is to stop someone doing this :
object.telephoneNumber = "not a telephone number".
If you used a setter you could do this :
public void setTelephoneNumber(final String telephoneNumber) {
if (telephoneNumber==null||telephoneNumber.length()==0) {
throw new IllegalArgumentException("you cannot supply null telephone numbers");
}
... etc.
this.telephoneNumber = telephoneNumber;
}
In this manner your telephoneNumber member variable will only ever hold a valid telephoneNumber. Your class is now totally self contained (encapsulated) because you are not relying on external classes to treat your member variables with respect.
Setters and getters are used to achieve Encapsulation.
Yes, we can make it work without setters and getters.
Why do we exactly need to use the set and get methods in our class that use private attributes?
The Getters() and Setters() methods called also Accessors and Mutators are used so we can acces the private fields in a class from outside.
public class myClass(){
public void newDog(){
Dog d=new Dog("Foxy", 2);
d.setDogAge(d.getDogAge()+1);//get the age of the dog and increment it
}
}
When it is really used during our program process?
They are used when we need to achieve read(with getters)/write(with setters) operations with our private fields(like in the previous Example).
Can we still make it work without it?
Yes, of course we can if we declare those fields as public(default case):
String dogName;
int dogAge;
And the prvious example will be:
public class myClass(){
public void newDog(){
Dog d=new Dog("Foxy", 2);
d.dogAge=d.dogAge+1;//get the age of the dog and increment it without getters and setters
}
}
Take a look at TutorialsPoint's Encapsulation Tutorial for further information.
Getters and setters are indeed for the principle of encapsulation, there is a good explanation in the answer here. According to convention getter and setters cannot add any functionality besides storing and retrieving the property. Since this is the only thing these methods do, there is a growing support for setting these variables to public and access them directly, without these methods. Since these methods just expose them publicly, there is no functional difference. For convention, and some frameworks, getters and setters are expected.
You can always let your IDE (Eclipse, IntelliJ, Netbeans) write the getters and setters for you. But if you want your code to be DRY and easy to read you can also consider using Lombok, which makes the getters and setters for you automatically.
Why do we exactly need to use the set and get methods in our class that use private attributes?
This term "Encapsulation" comes under Object oriented programming. Encapsulation is you hide the implementation but giving access.
When it is really used during our program process?
Getters are there to get some value where setters are to set a value. In your code you set Dogs name as a String and age as an int. Finally you have getters to get the set value.
Can we still make it work without it?
Yes. You can make it work by changing the private declared variables to public. Actually private keyword will make that variable visible only to the class where it is declared.
This gives you an in detail explanation about Objects.
http://docs.oracle.com/javase/tutorial/java/concepts/object.html
Does anyone know if there is a plan to add in implicit getters and setters for Class variables?
I'm thinking of the current Scala code that allows this already. Something like the following, where if you don't define a getter/setter it uses the value, but if you do define a getter/setter for the value it uses that instead of a direct variable call.
class A{
int value = 3;
}
class B{
int value = 3;
public int value(){
return value;
}
}
// in some method
A a = new A();
System.out.println(a.value);
B b = new B();
System.out.println(b.value); // <-- no () for accessing value even though it uses the getter
not Java per se, but there is this Project Lombok
Foreword: maybe I'm wrong but the question is maybe a better fit for java platform user/devel lists, like those at http://www.oracle.com/technetwork/java/javase/community/index.html
I suppose you'll receive more meaningful answers there, and less speculation.
My own take on the subject is that the JavaBean model is far too established to admit any significant change for backward compatibility, and that java encapsulation model is based on the concept that you hide fields with private access and provide accessors/mutators.
If you only want to expose members you can simply make them public.
Translating fields to automatic accessor/mutator methods is quite a big change to the language, and would probably create much confusion for little gain.
You should also consider that the scala choice implies a radically different approach to member access, for the sake of uniform access principle.
A simple getter returns a field value. However a getter can also return the results of an operation:
public boolean isError()
{
return errorList.size() > 0;
}
Similarly a setter might do other operations:
public void setName(String name)
{
this.name = name;
this.sortName = name.toLowerCase();
}
So other than the bean paradigm, and for the sake of consistency, getters/setters should be used rather than direct field access.
Java 14 (LTS release) has records, but you need to compile with additional options for it to work. Records provide getters for the constructor params and aim to solve a few other problems inherent in earlier versions.
Say I have some class:
public class A {
private int val = 0;
public int getVal() {
return val;
}
public void addFrom(A otherA) {
this.val += otherA.val;
if (otherA.val > 0)
otherA.val = 0;
else
otherA = Math.abs(otherA.val);
}
}
Should I be using getter methods instead to use otherA's val variable? Is it better style to do so?
Edit: This is a very simplified version of a class that takes much too long to read. But assume that there IS lazy initialization going on, that there are other methods that access this class, etc. I have updated the example method so that this may be more clear, but I hope it is clear that my question involves accessing the other object's variables, and want to know if it is faux pas to use a direct variable access for something that is not "this".
No, absolutely not.
You should use the variable directly when you're inside the class' members, and use getters in every other situation (when you would get an error because val is private anyway).
public int getVal() is intended to present your gift(variable) within a box to the outside world (encapsulation). Do you give gifts yourself in a box? It's weird, so use the variable as it is.
You can use variables, but the current code does not compile. Probably, the return should be int instead of boolean.
Probably, your intention is to override the compareTo method from the Comparable interface
Adding an unnecessary getter reveals internal structure and this is an opportunity for increased coupling.
A truly well-encapsulated class has no setters and preferably no getters either. Rather than asking a class for some data and then compute something with it, the class should be responsible to compute something with its data and then return the result.
Use of accessors to restrict direct access to field variable is preferred over the use of public fields, however, making getters and setter for each and every field is overkill. It also depends on the situation though, sometimes you just want a dumb data object. Accessors should be added for field where they're really required. A class should expose larger behavior which happens to use its state, rather than a repository of state to be manipulated by other classes.
Despite Java tutorials, Wikipedia searches, stackoverflow trolling, and hours of reading code samples, constructors still confuse the crap out of me. I've got three related questions that I've been trying to answer to help ME understand constructors a little better.
First, I've been under the impression that constructors need to be named the same as their classes. Consider:
public class Money {
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
public long getLong() {
return this.value;
}
public String getString() {
return toString(this.value);
}
}
I see this as four constructors...correct? So it appears that constructors not named the same as the class which contains them allowable. Can someone confirm that?
Second, I seem to have a block against understanding the set and get methods. Consider:
public class GetSetSample {
public int getFoo() {
return int Foo;
}
public void setFoo(int fooValue) {
int Foo = fooValue;
}
}
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
and use foo = getFoo(12) from some other class/method?
The third question is a little more esoteric, but will help me conceive of the bigger picture...which is my learning style, and conducive to my ability to trace program flow when debugging. The get and set methods suggest a "to" and "from" relationship to me. e.g., Passing a value "to" a constructor, receiving the result "from" the get method. It seems to me though that the "to" and "from" will change depending on your perspective. I think that any setMethod is setting parameters for an object, even though the variable comes FROM another class or method, and the GetMethod is getting the resulting object (say, this.foo) with the appropriately set parameter. No matter where the get or set is used, in a main method or a standalone class with a single constructor, 'set' is always associated with sending a parameter and get is always associated with receiving an object with that parameter. Is that a good understanding? or am I missing a vital part?
Question 1:
I see this as four constructors...correct?
No, that class has two constructors and two methods. (getLong and getString are the methods.)
Question 2:
Why can't I just do this:
public class getFoo(int fooValue){
foo=fooValue;
}
Well, that's trying to declare a class with parameters, and also you're setting a value in a get method, which would be extremely weird. It's not clear what you're trying to achieve here, but that code is thoroughly invalid.
Question 3:
The get and set methods suggest a "to" and "from" relationship to me.
Well it's not really a relationship IMO. A relationship suggests something longer term than either of these methods. A setter typically changes the state of an object in some way, and a getter typically just returns some aspect of the state of an object. It's not really clear what the rest of your explanation meant, because you're playing somewhat fast and loose with terminology. For example: "get is always associated with receiving an object with that parameter" doesn't really make sense to me. Objects don't have parameters, methods/constructors do - and getters can fetch primitive values or references...
I suspect you would benefit from reading the "Classes" part of the Java tutorial, which talks about constructors and methods.
Regarding the first answer, there's only 2 constructors. The difference is on how they are going to be called (called using a string will use the construction having a string has a parameter and called using a long will use the other one). So to answer, yes a constructor has the same name as the class.
The two constructors :
public Money(long l) {
this.value = l;
}
public Money(String s) {
this.value = toLong(s);
}
Regarding the second answer, getters ans setters are not meant to be classes. They are supposed to be within the class itself.
Consider this example which uses getter and setters to get ans set value for the printer class :
public class Printer {
#Inject #Informal Greeting greeting;
private String name;
private String salutation;
public void createSalutation() {
this.salutation = greeting.greet(name);
}
public String getSalutation() {
return salutation;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
A good read of this link could definitly help you out !
Java oriented-object principles
You've shown 2 constructors, which do need to have the same name as the class.
You've also shown two "getter" methods, which return the value of the class variable in the form requested by the user. You can also create "setter" methods, which are used to transfer values into class variables.
You use a constructor to create an object of a particular class, and optionally to set some or all of its internal state (that is, its member variables).
You use setters and getters to isolate the class variables from the outside world, so you don't need to allow other code to access them directly. Why? Because, before a setter updates a variable, it can verify that the new value is valid, and that the operation doesn't violate any or the rules (the "business logic") that are required for the class to work properly.
So you could add a setter and update the constructor to use it:
public Money(long l) {
setValue(l);
}
public Money(String s) {
setValue(toLong(s));
}
// Example setter that validates `l` by prohibiting negative values
public Money setValue(long l) {
if (l < 0) {
// Warn about negative values
}
this.value = l;
return this; // Return the current object to allow chaining; see below.
}
Note that a setter usually doesn't need to return a value (that is, it can be type void), but it's often helpful to return the object itself. That allows you to write code like this:
Money earnings = new Money().setValue(4).setOtherField("foo");
This creates an object of type Money, sets various attributes, and stores it in the variable earnings. Clearly, this isn't terribly useful for a simple class like this, but it can be very helpful for more complex classes:
Paycheck check = new Paycheck("MyCompany")
.setEmployee("YourName")
.setSalary(50,000)
.setPaySchedule(Schedule.BIWEEKLY)
.setAccountNumber("1234567")
.setDefaultTaxRate();
I would like to try to answer your implied conceptual questions -- you've already got plenty of examples of this and that, so I'm just going to try to explain. I have no doubt you have heard most of this -- maybe all of this -- before, but am not sure and not sure which parts.
Object-oriented programming centers mostly around objects; an object is an amalgamation of code and data. You define objects by writing a class, and you create one or more copies of the object defined by that class with the class constructor (called instantiating the class).
A parallel in other languages: you can have a data structure of related items and a set of subroutines that operate on that data structure. Think of a class as a way of collecting the items in that data structure and the subroutines that operate on it into one unit.
After you have invoked a constructor, you have a copy of the data defined in that class and a way to refer to that copy. By referring to that instance when you invoke a class method, you operate on that copy of the data with the methods defined in that class.
If you were to do this in a non-OO language, you could have a routine that created a copy of the data structure in memory and then only use the methods prescribed for it on that data structure. You could have a pointer to the copy in memory and pass that pointer as a parameter to every subroutine that operated on it, and in fact that's the way some pre-OO systems were programmed.
A constructor is similar to a method call that returns a value; it involves (or can involve) the execution of statements, and it always returns an object of that class. There are also differences between a constructor and a method; until the constructor completes, for instance, the object is not fully created and shouldn't have some methods invoked on it.
So I hope that helped; if there are conceptual things you still have questions about, perhaps something in here will help you form a specific question so we can explain things further.
Many people have found that if they have spent years learning languages such as COBOL and FORTRAN then changing to OO programming involves unlearning the old languages. I certainly found this when I first tackled C++ 20 years ago. From your description you are clearly struggling with the concepts and I sympathize.
I don't think there is a simple recipe. Practice at the simple examples and don't be disheartened. Don't be afraid to ask on SO - if the questions are clearly asked you will get a useful answer.
Get a good IDE (Eclipse, Netbeans, etc.) which allows you to "look inside" objects with the debugger. Hopefully at some stage things will click!
Question 1 - Basic Java Classes:
There's pretty much only 3 things you're going to find in a Java class
Field/attribute (Depending on your language of origin)
Method
Constructor (Which looks like a special kind of method)
Every class is going to have a class name that shares the name of the file it's located in. So to expand Money out a bit:
Money.java
----------
public class Money {
// This is a field/attribute
Long value;
// This is a constructor
public Money() {
this.value = Long(0L);
}
// This is a method
public Long getValue() {
return value;
}
// Another method
public void makeMoney(Long moreMoney) {
this.value = this.value + moreMoney;
}
} // Everything in here is part of the Money class
The only distinction between a constructor and a method is that a constructor has no specified return value, which is declared as a type right before the name of a potential method. Constructors do have to be named the same as the class they are contained in, but why is implied in how they are written.
Another way of looking at it is if you remove all of the non-type related Java keywords (public, private etc., but not things like float and int) from the front of the method you're looking at (A list of which you can find here), is there anything left in front of the method?
With the Money we have at the moment, it would look like this:
Money()
Long getValue()
void makeMoney()
The constructor is the one that has no type for the return value, because it is implied in the declaration.
Question 2/3 - Get/Set methods:
I'm going to say something potentially controversial, but don't worry about these yet. Get/Set are essentially patterns for Object Oriented development, and generally good Java style, but they aren't required (Last I checked, Android development actually discourages their use when possible for optimization reasons). Moreover, not all fields in your objects will be accessible or mutable so writing them isn't mandatory.
If you declare all of your fields as public (Like the 'value' field is implied to be right now), you simple can do this:
Money myMoney = new Money(new Long(40L));
System.out.println(myMoney.value) // 40
myMoney.value = new Long(20L);
System.out.println(myMoney.value) // 20
Aside from that, the notion of get() and set() are just methods. There is nothing special about them at all. The main reason they exist is because for general Object-Oriented programming, you shouldn't have to directly modify the internal workings of an object (This is the principle of Encapsulation). Everything you should need to affect state or get something out of it should be handled by a method.
In a pithy one-liner: If you need to know the fields of an object to use it, you designed it incorrectly.
Big Picture
So what get() and set() really are is a pair of commonly written methods that happen to affect a field in an object in an extremely simple way (get() is a simple access to a field, set() is assignment to that field). It's just that other methods you write will happen to do more complicated stuff than that.
My professor really emphasizes protecting against privacy leaks by always using accessors and mutators to access private instance variables; however, do I have to use the getters/setters of a class within the class?
So for instance, if I have the following class:
public class Person
{
private String name;
private int age;
}
and I want to write a toString() method for it. Can I just write:
public String toString()
{
return name + " " + age;
}
OR do I need to do something like this:
public String toString()
{
return this.getName() + " " + this.getAge();
}
You CAN do either one. However, your professor might appreciate using the methods instead of the direct access. Here's why.
Let's say you have a class like this:
class SomeClass {
private int someValue;
private String someString;
public SomeClass(int someValue, String someString) {
this.someValue = someValue;
this.someString = someString;
}
public int someValue() {
return this.someValue;
}
public String someString() {
return this.someString;
}
public String toString() {
return someValue + ": " + someString;
}
}
It's pretty straightforward, right? Well, what if all of a sudden we want to CHANGE the implementation of how we calculate someValue, and base it off of someString:
public int someValue() {
int value = 0;
for(int i = 0; i < someString.length; i++) {
if(someString.charAt(i) == ' ') value++;
}
return value;
}
Now you also have to change every place where variable someValue was used.
So if you want to make the code easier to maintain in the long run, use the methods calls. This way when you code changes on you (and trust me, it changes all the time) you only have to change it in one spot instead of two.
And yes, you would want to use a method call in getting someString instead of the direct access in the last method :-)
When I design a class I try to make a clear distinction between the inside (implementation details) and the outside (the interface exposed to the world). Getters and setters provide a convenient place to convert values between the form in which they are stored in the object’s instance members and the form in which the outside world sees them. Using getters and setters internally would muck that up, because they'd be getting used by both the inside and outside.
If you find yourself wanting to hide part of a class from another part of the same class, consider breaking off the part you want to hide into its own class.
It's normally not a good idea, for a number of reasons:
You may not even want accessors for all fields
Some accessors may make a defensive copy so not to expose internal state, this is normally unnecessary within the class where you know that you are not going to modify it - or plain wrong if you know you ARE going to modify it
It makes debugging more annoying, because you have to follow the getters / setters
It makes reading the code harder in most IDEs, since most of them color fields differently than local variables
... but as always, there are exceptions. Some setters may have side-effects (for example setting a second value) that you WANT to execute, then it might be better to use the setter. Also, if you design your class for inheritance, it may be better to go via an accessor if you want the subclass to be able to alter the behavior.
In general, no. If your getter returns something other than the value of the field then you should use the method, but in that rare case your method should have a more descriptive name. For a bad example, if you have:
public void setName(String name)
{
_name = name;
}
and your getter returned something else, like
public String getName()
{
return _name.toUpperCase();
}
then yes, you should use the getter. It would be better, though, to have a more descriptive name for that getter:
public String getNameAsUppercase()
{
return _name.toUpperCase();
}
You can use the accessors and mutators, but its a messy standard to follow.
It clutters up your code and confuses anyone trying to read it thinking it might not be a part of your class.
Basically, just access the variables directly from inside your class, and indirectly from anywhere else.
On the flip side, consider it from a design standpoint. One of the motivations for getters/setters is that the underlying data storage can change and things that implement the class won't need to be changed since it is encapsulated.
So, keeping that in mind, using getters/setters within the class makes future changes easier. Instead of having to find all the places that alter the member directly, you just have to change the getter/setter. Depending on the complexity of the class, this may significantly reduce the amount of work it takes to change the storage members.
For example, let's assume you start out with the age variable in years. Then you decide later to store it as seconds for some reason. But you want to always print it in years anyway. So in your example, you could do the math in your toString() function (and anywhere else that wants years as the units) or you can just change the math in the getAge() routine to return years from the seconds and nothing else has to change.
Obviously that example is a bit trivial. The more complicated the class, the more useful it is to use getters/setters within it.
No, you don't. You can access any variables, private, public or protected, from within the class.
Here are some tables to help you:
Source: Java Tutorials
If your class (or the accessor methods in question) is not final, then you should definitely use the accessor methods.
If another class extends yours and overrides those accessors, your class should use the overridden accessors. If this would break your superclass, then your superclass is designed incorrectly; prevent those accessors from being overridden with final, or change the design of your class.
No you can use directly your instance variables inside the class, you're not violating any "rule". Getters and setters are mandatory for others classes to access instance variables of a class to not violate the encapsulation principle (which is quite important in OO programming).
In the end it's a matter of choice, but you're saving one method call using your first example.
I think we should use getters() and setters() instead of accessing directly. It is also makes debugging very easy; for example, if you need to assign a variable to multiple place in your class and later want to find out from how many places the variable is assigned to, then you need to find all the assignment and set the break point.
However, if you use a setter you can simply put a break point inside the setter method and can see how many time the variable is assigned.
I use a mix of both. Accessor methods add more clutter so I use them only when the variable is used many times. If the variable is used only once or twice I don't use them.