Related
This question already has answers here:
Why are getter and setter method important in java? [duplicate]
(6 answers)
Closed 7 years ago.
Encapsulation is hiding the data. I would like to hear some really interesting answers here.
What is the point behind keeping variables as private when we already declare public setter methods for variables?
I understand the usage of encapsulation but when we are making the setters as public what is the point behind keeping the variables as private, we can directly use public access modifiers.
Is it because we do not want others to know the exact way we are storing data or managing data on the back-end?
Is it because we do not want others to know the exact way we are
storing data or managing data on the back-end?
Yes, that's the point. It is related to the concepts of abstraction and information hiding too.
You provide a public setter that when invoked by the class client will have the effect that you have documented. It is none of the client's business how this effect is actually achieved. Are you modifying one of the class attributes? Ok, let the client know that, but not the fact that you are actually modifying a variable. In the future, you could want to modify your class so that instead of a simple backup variable it uses something completely different (a dictionary of attributes? An external service? Whatever!) and the client will not break.
So your setter is an abstraction that you provide to the client for "modify this class attribute". At the same time you are hiding the fact that you are using an internal variable because the client doesn't need to know that fact.
(Note: here I'm using the word "attribute" as a generic concept, not related to any concrete programming language)
I fully agree with Konamiman's answer, but I'd like to add one thing:
There are cases where you really don't want that abstraction. And that's fine.
A simple example I like to use here is a class for a 3-dimensional float vector:
class Vector3f {
public:
float x;
float y;
float z;
};
Could you make those fields private and provide setters instead? Sure, you could. But here you might argue that the class is really just supposed to provide a tuple of floats and you don't want any additional functionality. Thus adding setters would only complicate the class and you'd rather leave the fields public.
Now, you can easily construct scenarios where that might bite you later on. For instance, you might one day get a requirement that Vector3fs are not allowed to store NaNs and should throw an exception if anyone tries to do so. But such a hypothetical future problem should not be enough to justify introducing additional abstractions.
It's your call as a programmer to decide which abstractions make sense for the problem at hand and which ones would only get in your way of getting the job done. Unnecessary abstractions are over-engineering and will hurt your productivity just as much as not abstracting enough.
Bottom line: Don't blindly use setters everywhere just because someone claimed that's good practice. Instead, think about the problem at hand and consider the tradeoffs.
Because by encapsulation we provide single point of access. Suppose you define a variable and its setter as follows
String username;
public void setUsername(String username){
this.username = username;
}
Later you like to add some validation before setting username property. If you are setting the username at 10 places by directly accessing the property then you don't have single point of access and you need to make this change at 10 places. But if you have one setter method then by making a change at one place you can easily achieve the result.
Think about this : I'm representing a real life object, a Lion through a class. I'd do something like this.
class Lion {
public int legs;
}
Now my class is needed by some other developer to create an object and set its legs field. He'd do something like this
Lion jungleKing = new Lion();
jungleKing.legs = 15;
Now the question is, Java won't restrict him to setting any number more than 4 as the number of legs for that object. It's not an error, and it'll run just fine. But it's a logical blunder, and the compiler won't help you there. This way a Lion may have any number of legs.
But if we write the code this way
class Lion {
private int legs;
public void setLegs(int legs){
if(legs > 4){
this.legs = 4;
}
else this.legs = legs;
}
}
Now you won't have any Lion with more than 4 legs because the policy of updating the fields of the class has been defined by the class itself and there's no way anyone not knowing the policy is going to update the legs field because the only way to update the legs field is through the setLegs() method and that method knows the policy of the class.
Although Konamiman's answer is spot on, I'd like to add that, in the particular case of public setters versus directly exposing public fields you are asking, there is another very important distinction to keep in mind apart from information hiding and decoupling implementation from the public surface, or API, of a class; validation.
In a public field scenario, there is no way to validate the field's value when it's modified. In case of a public setter (be it a Foo {get; set;} property or a SetFoo(Foo value)) method you have the possibility to add validation code and launch required side-effects and this way ensure that your class is always in a valid or predictable state.
What if you do want to a range check before assignment? That's one of the cases I use setters and getters
More or less simple and realistic example I encountered in practice is an Options class, which has a lot of setters and getters. At some point you might want to add new option which depends on others or has side effects. Or even replace group of options with Enum. In this case setA function will not just modify a field, but will hide some additional configuration logic. Similarly getA will not just return value of a, but something like config == cStuffSupportingA.
Wikipedia has a good overview of [mutator methods(https://en.wikipedia.org/wiki/Mutator_method), which is what setter methods are and how they work in different languages.
The short version: if you want to introduce validation or other logic that gets executed on object modification it is nice to have a setter to put that logic in. Also you may want to hide how you store things. So, those are reasons for having getters/setters. Similarly, for getters, you might have logic that provides default values or values that are dependent on e.g. configuration for things like Locale, character encoding, etc. There are lots of valid reasons to want to have logic other than getting or setting the instance variable.
Obviously, if you have getters and setteres, you don't want people bypassing them by manipulating the object state directly, which is why you should keep instance variables private.
Other things to consider include whether you actually want your objects to be mutable at all (if not, make fields final), whether you want to make modifying the object state threadsafe with e.g. locks, synchronized, etc.
Setting fields as private documents a powerful fact: these private fields are only directly used within the current class. This helps maintainers by not having to track down field usage. They can reason better on the code by looking at the class and determining that the effects on and from these fields with the class' environment go through public and protected method calls. It limits the exposure surface on the class.
In turn, defining a "setter" for a private field is not about giving it publicity again. It is about declaring another powerful fact: an object belonging to this class has a property that can be modified from the outside. (The terms object and property are used in the sense of a bounded part of the whole and an observable fact about this part, not in the OOP sense)
Why then declare a "setter" on a field when making the field public would suffice? Because declaring a field not only binds a name to a property of the objects of the class, but also commits to use memory storage for this property.
Therefore, if you declare a "private field with a setter", you declare three things:
You declare that the name you gave to the field/setter cluster represents a property of the object which is of interest when the object is seen as a black box.
You declare that the value of this property is modifiable by the environment of the object.
You declare that in this particular concrete class, the property of the object is realized by committing some memory storage to it.
I advocate that you never make your fields private with getters and setters indiscriminately. Fields are for describing storage. Methods are for interactions with the environment. (And the particular case of "getters" and "setters" are for describing properties of interest)
This question already has answers here:
Why are getter and setter method important in java? [duplicate]
(6 answers)
Closed 8 years ago.
If I create a class in Java, I've always been taught that the convention is to make all fields of a class private. If I need to access or change them, I can create an accessor and mutator method. I do understand the importance of private variables, as they help reduce complexity and allow for encapsulation.
What I don't understand is that if I create a public accesor and mutator method, isn't the variable public at that point? Why is it still convention to use private variables in situations where anyone can access them?
I should also note that I understand the important of these methods, but I would like to know why we bother to make the variable private even though we are giving anyone access to it through those methods?
Yes, you're right, it does effectively make the variable public. But there's one important difference, which is that it gives you the ability to change things later on: you can remove the setter if you want, or make it private, without affecting code that reads from the field using the getter.
If you'd just made the variable public, you wouldn't be able to stop writes to the field without also breaking reads from the field.
It has other advantages. You can make the access synchronized if you want to later on, without breaking client code, for instance. In short, it allows lots of modifications later on that wouldn't otherwise be possible without causing lots of breakages in code that uses the class.
And you can add extra logic that logs whenever someone writes to the field, or prevents certain threads from writing, or whatever... you can change the type of a field from a HashMap to a TreeMap if your getter abstracts it away and just returns a Map... etc.
Private fields are considered to be internal to the object. So the outside world doesn't need to know about how the data is stored inside the object. This means you can easily change the internal representation of data of an object while everyone else still uses the same accessors / mutators to do its work.
It's also possible that accessors / mutators perform validation and other steps that are needed internally for the object but that you don't wish to expose to code that uses the object.
You could make all fields public but that limits your ability to change the internal structure of the object later on when a lot of code now depends on a field being named a certain way.
I am learning get and set methods, I was just wondering if these can only be public, and do they need to be written for every instance variable in a class?
No.
Many internal variables should never be edited, such as states of computations.
If a field is private and has no getter/setter, it is that way for a reason and is acceptable as long as you don't need to access it outside the class.
If it is public, there's no point, and if protected, it's per-package or subclasses not necessarily in the same package.
Without a modifier, it's package-private.
If you want to make a field private and the getter/setter controlled you can use access levels as well.
On that note, if you want, you can perform validation inside a setter to ensure only acceptable values are set. Then, you can either silently reject, return false if the setter is a boolean, or throw an exception in severe circumstances.
I am assuming you are talking about encapsulation.
The whole point of these methods is for them to be public so that they can pass the value of your variable somewhere else in the application.
For achieving this with many variables, you may consider using 'listeners' (Observer Pattern Theory) which are basically custom interfaces that work with a custom class that contains many of these get and set methods.
More on encapsulation:
http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)
More on Observer Pattern Theory
http://www.youtube.com/watch?v=UEtyGP994X0
You need to have public getters and setters for your object to function as a JavaBean.
If you don't have a JavaBean requirement for your objects, then you don't need/have to provide public getters ( and especially setters ) in your classes.
Get and set methods in Java are just normal methods. They don't have to be public, but they wouldn't be very useful if they weren't public.
They don't need to be written for every instance variable in a class. If there are instance variables whose values depend on other values, then it may not make sense for them to have setters, e.g. a totalPrice instance variable that depends on a quantity instance variable.
If you want instance variables that shouldn't change, i.e they are immutable, then don't provide any set methods at all.
These methods provide your interface to the caller. They provide the operations on your object that you allow, so that the caller can't set your values to an invalid state, e.g. a count of -1 or a latitude of 91 degrees. This is "encapsulation", or hiding your object's implementation from your caller.
There is no java rule for making getters and setters public but these are made public for a reason.The point of getters and setters is that only they are meant to be used to access the private varialble, which they are getting or setting. This way you provide encapsulation and it will be much easier to refactor or modify your code later.Using getter and setter functions allow for constraints and encapsulation. Lets say x is the radius. shape.x = -10 would not make much sense. Also, if someone tries to set an illegal value, you can print an error, set a default value, or do nothing. It is good practice to make member variables private so they cannot be modified directly by programs using them.
A good article on the usage of getters and setters:
http://java.dzone.com/articles/getter-setter-use-or-not-use-0
Basically Yes, and No.
Yes, Get and Set methods (also called "getters" and "setters" or accessor methods) should almost always be public (although they can be otherwise -- there's a difference between can and should). The point of getters and setters is usually so other classes can access the encapsulated instance variables.
Exeptions:
You might make an accessor method to be protected if you only want child
classes or other classes in the same package to have access to those
methods.
You might use a private (or protected) setter if you want to
use special logic to set a variable (like concatenating it)
and you don't want other classes to be able to set the
variable.
No, they shouldn't always have accessors. Sometimes a variable should only have a getter (for instance, if that variable is final), and sometimes a variable shouldn't be accessed at all, and therefore you would not give it any accessor methods.
Get and set methods were designed originally for JavaBeans, classes stylized so IDEs and application programs can detect what properties the classes have and what event listeners they support. Through a limited version of reflection called introspection, tools can analyze the classes, and even if the programmer did not want to use is/get/set methods he could write BeanInfo classes that tell what methods be used instead.
Look at the Javadoc for java.beans.Introspector. and java.beans.BeanInfo. This provides ways to document additional information, including methods exposed to other tools and metadata about properties. For example, a TemperatureGauge class could expose the minimum and maximum temperature so a Swing program can set the limits of a slider without the programmer looking the information up.
Still, one should not expose more than one has to expose. You may need to limit access to getters and setters. You may need them for database tools, but you may not want ordinary programming to touch properties. This leads to ideas like OSGI or proxies where methods are limited to specific packages.
For example, one common tactic is to have getters only, to mark variables final, and build objects in the constructor. For example,
public final class Complex {
private final double re;
private final double im;
public Complex(double re, double I'm) {
this.re = re;
this.im = im;
}
public double getReal() {
return re;
}
// more getters, arithmetic, etc.
}
Note that I named the method slightly differently than the variable; that's okay.
On the other hand, there is a style of programming where one eschews getters and writes methods that tell the object what to do. Consider a Name class with givenName and surname instance variables. Then, add this method:
public void writeFormally(Appendable app) {
app.append(surname)
.append(", ")
.append(givenName);
}
You see this sometimes in Model-View-Presenter systems, like GWT and its HasText interface.
Unless you are writing code that deals with dependency injection systems or that use reflection to have your objects communicate with database, don't worry about the specifics of getters and setters. Just do what comes naturally and limit your objects' exposures. Also, every time you are tempted to write:
x.getA().getB().getC().setZ(42);
Rewrite the code to get rid of the chain of gets and sets. Look up the Law of Demeter in The Pragmatic Programmer.
Use protected if you want only child classes to access the field. However, if you want other classes to access the field, public is the way to go. Your decision should be based on the scope of access.
I want to force future users of a class to access a private member also from future code written in that class only through an accessor method (even through junit or anything like that).
is there a way to do it in java? can someone show an example if possible?
You cannot force to do that, but you can create a method and document that enforcement in the javadoc.
private int myMember;
/**
* ATTENTION: use this method instead of setting the member directly.
*/
public void setMyMember(int value) {
this.myMember = value;
}
Also, there is an alternative solution which might work. Use ThreadLocal, like this:
private final ThreadLocal<String> member = new ThreadLocal<String>();
public void setMember(final String value) {
member.set(value);
}
The member field is final and cannot be changed. Therefore, clients will be forced to call the setter directly.
As long as the field is part of the class, anyone can access it directly. This can be a problem when we try to force all (co-)authors to go through the getters/setters because those method do some conversion, checking or bookkeeping stuff. Like incrementing internal counters.
A general solution, that comes to mind: it could be possible by using annotations. You'd have to create an annotation (and the annotation processor code) to ensure, that it is a compile time error if the field is used outside of it's getter/setter method:
#GetterSetterAccessOnly
private int value;
If you want to prevent reflection you can use a SecurityManager. If this is not an option you can get the call stack with Thread.currentThread().getStackTrace() and check the caller is from your class.
Two problems with this are; the performance won't be great. Anything you can do in the method you can do externally so the simplest work around is to copy its contents without the check. ;)
I suggest you document your reason for not allowing access this way.
Make use of inheritance to hide the field:
Do your class with all the fields and getter/setters that you need. (You may make it abstract)
Do a child class, that inherits from the previews one, and since the field isn't accessible, you force the use of the getter/setter pair.
As you are talking about the accessing in the same class, they have all the freedom to access the private member directly as well as through accessor method if that member has. So basically you cannot prevent them using the member directly in the same class.
I am afraid there is no standard way to do that. If a user has access to a class instance, although a private member is declared private, permissions can be changed at runtime and accessed anyway.
You need a classloader that enforces permissions. You can make an OSGi Bundle and enforce a control policy over the instance of your objects exported as services through interfaces. However this will tie you to an OSGi container to run your application.
Well, if they have access to your code, they can do anything they want. In the worst case, they remove your getters and setters and just put in a public field instead ;)
But of course you can motivate them to not access the variable directly with an according design:
you should check whether the others should rather implement subclasses instead of changing the class itself. Then private fields are, of course, only accessed via setters and getters.
you could move the data into a different class, and use your getters and setters to access the data in the other class. Doing this just for the sake of not having the data directly in your class is maybe a bit counter-intuitive, but since you probably have a good reason why they shouldn't access that very data, it indicates a different responsibility. So refactoring to meet the SRP is a good idea anyways.
I am new to programming. I am learning Java now, there is something I am not really sure, that the use of private. Why programmer set the variable as private then write , getter and setter to access it. Why not put everything in public since we use it anyway.
public class BadOO {
public int size;
public int weight;
...
}
public class ExploitBadOO {
public static void main (String [] args) {
BadOO b = new BadOO();
b.size = -5; // Legal but bad!!
}
}
I found some code like this, and i saw the comment legal but bad. I don't understand why, please explain me.
The most important reason is to hide the internal implementation details of your class. If you prevent programmers from relying on those details, you can safely modify the implementation without worrying that you will break existing code that uses the class.
So by declaring the field private you prevent a user from accessing the variable directly. By providing gettters and setters you control exactly how a user may control the variable.
The main reason to not just make the variable public in the first place is that if you did make it public, you would create more headaches later on.
For example, one programmer writes public getters and setters around a private member variable. Three months later, he needs to verify that the variable is never "set" to null. He adds in a check in the "setFoo(...)" method, and all attempts to set the variable will then be checked for "setting it to null". Case closed, and with little effort.
Another programmer realizes that putting in public getters and setters around a private member variable is violating the spirit of encapsulation, he sees the futility of the methods and decides to just make the member variable public. Perhaps this gains a bit of a performance boost, or perhaps the programmer just wants to "write it as it is used". Three months later, he needs to verify that the variable is never "set" to null. He scans every access to the variable, effectively searching through the entire code base, including all code that might be accessing the variable via reflection. This includes all 3rd party libraries which has extended his code, and all newly written modules which used his code after it was written. He then either modifies all calls to guarantee that the variable is never set to null. The case is never closed, because he can't effectively find all accesses to the exposed member, nor does he have access to all 3rd party source code. With imperfect knowledge of newly written modules, the survey is guaranteed to be incomplete. Finally he has no control over the future code which may access the public member, and that code may contain lines which set the member variable to null.
Of course the second programmer could then break all existing code by putting "get" and "set" methods around the variable and making it private, but hey, he could have done that three months earlier and saved himself the explanation of why he needed to break everyone else's code.
Call it what you will, but putting public "get" and "set" methods around a private member variable is defensive programming which has been brought about by many years (i.e. decades) of experience.
Anything public in your class is a contract with the users of the class. As you modify the class, you must maintain the contract. You can add to the contract (new methods, variables, etc.), but you can't remove from it. Idealy you want that contract to be as small as possible. It is useful to make everything private that you can. If you need direct access from package members, make it protected. Only make those things public which are required by your users.
Exposing variables means that you are contracting forever, to have that variable and allow users to modify it. As discussed above, you may find you need to invoke behaviour when a variable is accessed. This can be be done if you only contract for the getter and setter methods.
Many of the early Java classes have contracts which require them to be thread safe. This adds significant overhead in cases where only one thread can access the instance. Newer releases have new classes which duplicate or enhance the functionality but drop the syncronization. Hence StringBuilder was added and in most cases should be used instead of StringBuffer.
Its considered bad mainly because you loose control over who can change the value and what happens when the value changes.
In tiny application written by you for you it won't seem that important but as you start developing for larger and larger applications having control over who changes what and when becomes critical.
Imagine from your example above, you publish library as is, other people use it, then you decide you wanted to calculate another value in your bad class when the size changes ... suddenly the bad00 class has no way of knowing and you can't change it because other people rely on it.
Instead if you had a set method you could extend it to say
void SetSize(int newSize)
{
size = newSize;
DoCalculation;
}
You can extend the functionality without breaking other peoples reliance on you.
I highly recommend the book Effective Java, it contains a lot of useful information about how to write better programs in Java.
Your question is addressed in items 13 and 14 of that book:
Item 13: Minimize the accessibility of classes and members
Item 14: In public classes, use accessor methods, not public fields
You shouldn't allow implementations to alter your records directly. Providing getters and setters means that you have exact control over how variables get assigned or what gets returned, etc. The same thing goes for the code in your constructor. What if the setter does something special when you assign a value to size? This won't happen if you assign it directly.
It's a common pet-peeve of many programmers - Java code with private fields and public accessors and mutators. The effect is as you say, those fields might as well been public.
There are programming languages that voice for the other extreme, too. Look at Python; just about everything is public, to some extent.
These are different coding practices and a common thing programmers deal with every day. But in Java, here's my rule of thumb:
If the field is used purely as an attribute, both readable and writeable by anyone, make it public.
If the field is used internally only, use private. Provide a getter if you want read access, and provide a setter if you want write access.
There is a special case: sometimes, you want to process extra data when an attribute is accessed. In that case, you would provide both getters and setters, but inside these property functions, you would do more than just return - for example, if you want to track the number of times an attribute is read by other programs during an object's life time.
That's just a brief overview on access levels. If you're interested, also read up on protected access.
This is indeed used to hide the internal implementation. This also helps is providing extra bit of logic on your variables. Say you need to make sure that the value passed for a varable should not be 0/null, you can provide this logic in the set method. Also in the same way you can provide some logic while getting the value, say you have a object variable which is not initialised and you are accessing that object, in this case you cand provide the logic to null check for that object and always return an object.
C# programmers use this equally as much, or maybe more frequently than I see in Java. C# calls it properties where in Java it is accessors/mutators
For me it makes sense to have getter and setter methods to encapsulate the classes so that no class can change the instance variables of another class.
Okay. We are talking about Objects here. The real world objects. If they are not private,the user of your class is allowed to change. What if for a Circle class, and for the radius attribute/property of the Circle class, the user sets value as '0'. It doesn't make sense for a Circle to exist with radius as '0'. You can avoid such mistakes if you make your attributes private and give a setter method and in which and throw an Exception/Error (instructing the user ) that it is not allowed to create a Circle with radisu as '0'. Basically, the objects that are created out of your class - are meant to exist as you wished to have them exist. This is one of the ways to achieve it.
As stated earlier, the reason for making a variable private is to hide it from the outside. But if you make a getter AND a setter then you may as well make the variable itself public. If you find yourself later in a position that you made the wrong choice, then you must refactor your code from using the public variable into using the getter/setter which may not be a problem. But it can be a problem if other code, which you do not control, starts depending on your code. Then such a refactoring will break the other code. If you use getters and setters from the start you will reduce that risk in exchange for a little effort. So it depends on your situation.
It depends on who access these public variables. Most likely, only by people inside your company/team. Then it's trivial to refactor them into getters/setters when necessary. I say in this case, it's better to leave the variables public; unless you are forced to follow the java bean convention.
If you are writing a framework or a library intended for the public, then you shouldn't expose variables. It's impossible for you to change them into getters/setters later.
But the 2nd case is more rare than the first; people apply extremely unreasonable assumptions when it come to software engineer, as if they are not writing code, instead they are carving code in stone. And as if the whole world is watching while you code - in reality, nobody will ever read your code except yourself