I read Effective Java, and there written
If a class cannot be made immutable, limit its mutability as much as
possible...
and
...make every field final unless there is a compelling reason to make it
nonfinal.
So need I always make all my POJO(for example simple Bookclass with ID, Title and Author fields) classes immutable? And when I want to change state of my object(for example user change it in table where represented many Books), instead of setters use method like this:
public Book changeAuthor(String author) {
return new Book(this.id, this.title, author); //Book constructor is private
}
But I think is really not a good idea..
Please, explain me when to make a class immutable.
No, you don't need always to make your POJO immutable. Like you said, sometimes it can be a bad idea. If you object has attributes that will change over the time, a setter is the most comfortable way to do it.
But you should consider to make your object immutable. It will help you to find errors, to program more clearly and to deal with concurrency.
But I think you quoting say everything:
If a class cannot be made immutable, limit its mutability as much as
possible...
and
...make every field final unless there is a compelling reason to make
it nonfinal.
That's what you should do. Unless it's not possible, because you have a setter. But then be aware of concurrency.
In OOP world we have state. State it's all properties in your object. Return new object when you change state of your object guaranties that your application will work correctly in concurrent environment without specific things (synchronized, locks, atomics, etc.). But you always create new object.
Imagine that your object contains 100 properties, or to be real some collection with 100 elements. To follow the idea of immutability you need copy this collection as well. It's great memory overhead, perhaps it handled by GC. In most situation it's better to manually handle state of object than make object immutable. In some hard cases better to return copy if concurrent problems very hard. It depends on task. No silver bullet.
1. A POJO is one which has private Instance Variables with Getter and Setter methods.
2. And Classes like String class, which needs a constant behavior/implementation at all time needs to be
final, not the one which needs to change with time.
3. For making a class immutable, final is not only the solution, One can have private Instance variables, with only Getter methods. And their state being set into the Constructor.
4. Now depending on your coding decision, try to rectify which fields needs to be constant throughout the program, if you feel that certain fields are to be immutable, make them final.
5. JVM uses a mechanism called Constant folding for pre-calculating the constant values.
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)
I understand that it is a good practice to use final for object fields that are 1) set only once in the constructor 2) reference to an immutable object.
What about fields that are set only once in the constructor but reference to a mutable object?
Currently, I prefer using final only for immutable object references, because I can quickly see which fields represent the mutable state of the object (those that are not final).
Update: I know how final works technically, specifically that setting a reference to a mutable object as final won't make the object immutable. This question is about when exactly use final if I want to maximize clarity and understandability of the code.
This might not be a popular opinion, but I use final wherever possible - if you're using it to declare intent, then that can be done with comments. If your reaction to that is that "comments are bad", then you should reconsider the use of the final keyword also - as it's basically a comment, right?
However, the final keyword does provide a (almost) guarantee to anyone reading the code that that variable isn't reset anywhere (ignoring reflection of course...) - which is a useful thing to know at times.
You might also be interested in Jon's answer to this question
EDIT: Sorry, I should clarify that "wherever possible" applies to fields - not classes, methods etc. because that would be weird.
Even if you declare the variable final the referenced object will still be mutable. So if this is what you are trying to avoid then it would not work (I mean make the referenced object immutable)
As everybody knows, Java follows the paradigms of object orientation, where data encapsulation says, that fields (attributes) of an object should be hidden for the outer world and only accessed via methods or that methods are the only interface of the class for the outer world. So why is it possible to declare a field in Java as public, which would be against the data encapsulation paradigm?
I think it's possible because every rule has its exception, every best practice can be overridden in certain cases.
For example, I often expose public static final data members as public (e.g., constants). I don't think it's harmful.
I'll point out that this situation is true in other languages besides Java: C++, C#, etc.
Languages need not always protect us from ourselves.
In Oli's example, what's the harm if I write it this way?
public class Point {
public final int x;
public final int y;
public Point(int p, int q) {
this.x = p;
this.y = q;
}
}
It's immutable and thread safe. The data members might be public, but you can't hurt them.
Besides, it's a dirty little secret that "private" isn't really private in Java. You can always use reflection to get around it.
So relax. It's not so bad.
For flexibility. It would be a massive pain if I wasn't able to write:
class Point {
public int x;
public int y;
}
There is precious little advantage to hide this behind getters and setters.
Because rigid "data encapsulation" is not the only paradigm, nor a mandatory feature of object orientation.
And, more to the point, if one has a data attribute that has a public setter method and a public getter method, and the methods do nothing other than actually set/get the attribute, what's the point of keeping it private?
Not all classes follow the encapsulation paradigm (e.g. factory classes). To me, this increases flexibility. And anyway, it's the responsibility of the programmer, not the language, to scope appropriately.
Object Oriented design has no requirement of encapsulation. That is a best practice in languages like Java that has far more to do with the language's design than OO.
It is only a best practice to always encapsulate in Java for one simple reason. If you don't encapsulate, you can't later encapsulate without changing an object's signature. For instance, if your employee has a name, and you make it public, it is employee.name. If you later want to encapsulate it, you end up with employee.getName() and employee.setName(). this will of course break any code using your Employee class. Thus, in Java it is best practice to encapsulate everything, so that you never have to change an object's signature.
Some other OO languages (ActionScript3, C#, etc) support true properties, where adding a getter/setter does not affect the signature. In this case, if you have a getter or setter, it replaces the public property with the same signature, so you can easily switch back and forth without breaking code. In these languages, the practice of always encapsulating is no longer necessary.
Discussing good side of public variables... Like it... :)
There can be many reasons to use public variables. Let's check them one by one:
Performance
Although rare, there will be some situations in which it matters. The overhead of method call will have to be avoided in some cases.
Constants
We may use public variables for constants, which cannot be changed after it is initialized in constructor. It helps performance too. Sometimes these may be static constants, like connection string to the database. For example,
public static final String ACCEPTABLE_PUBLIC = "Acceptable public variable";
Other Cases
There are some cases when public makes no difference or having a getter and setter is unnecessary. A good example with Point is already written as answer.
Java is a branch from the C style-syntax languages. Those languages supported structs which were fixed offset aliases for a block of memory that was generally determined to be considered "one item". In other words, data structures were implemented with structs.
While using a struct directly violates the encapsulation goals of Object Oriented Programming, when Java was first released most people were far more competent in Iterative (procedural) programming. By exposing members as public you can effectively use a Java class the same way you might use a C struct even though the underlying implementations of the two envrionments were drastically different.
There are some scenarios where you can even do this with proper encapsulation. For example, many data structure consist of nodes of two or more pointers, one to point to the "contained" data, and one or more to point to the "other" connections to the rest of the data structure. In such a case, you might create a private class that has not visibility outside of the "data structure" class (like an inner class) and since all of your code to walk the structure is contained within the same .java file, you might remove the .getNext() methods of the inner class as a performance optimization.
To use public or not really depends on whether there is an invariant to maintain. For example, a pure data object does not restrict state transition in any fashion, so it does not make sense to encapsulate the members with a bunch of accessors that offer no more functionality that exposing the data member as public.
If you have both a getter and setter for a particular non-private data member that provides no more functionality than getting and setting, then you might want to reevaluate your design or make the member public.
I believe data encapsulation is offered more like an add-on feature and not a compulsory requirement or rule, so the coder is given the freedom to use his/her wisdom to apply the features and tweak them as per their needs.Hence, flexible it is!
A related example can be one given by #Oli Charlesworth
Accesibility modifiers are an implementation of the concept of encapsulation in OO languages (I see this implementation as a way to relax this concept and allow some flexibility). There are pure OO languages that doesn't have accesibility modifiers i.e. Smalltalk. In this language all the state (instance variables) is private and all the methods are public, the only way you have to modify or query the state of an object is through its instance methods. The absence of accesibility modifiers for methods force the developers to adopt certain conventions, for instance, methods in a private protocol (protocols are a way to organize methods in a class) should not be used outside the class, but no construct of the language will enforce this, if you want to you can call those methods.
I'm just a beginner, but if public statement doesn't exists, the java development will be really complicated to understand. Because we use public, private and others statements to simplify the understanding of code, like jars that we use and others have created. That I wanna say is that we don't need to invent, we need to learn and carry on.
I hope apologize from my english, I'm trying to improve and I hope to write clearly in the future.
I really can't think of a good reason for not using getters and setters outside of laziness. Effective Java, which is widely regarded as one of the best java books ever, says to always use getters and setters.
If you don't need to hear about why you should always use getters and setters skip this paragraph. I disagree with the number 1 answer's example of a Point as a time to not use getters and setters. There are several issues with this. What if you needed to change the type of the number. For example, one time when I was experimenting with graphics I found that I frequently changed my mind as to weather I want to store the location in a java Shape or directly as an int like he demonstrated. If I didn't use getters and setters and I changed this I would have to change all the code that used the location. However, if I didn't I could just change the getter and setter.
Getters and setters are a pain in Java. In Scala you can create public data members and then getters and or setters later with out changing the API. This gives you the best of both worlds! Perhaps, Java will fix this one day.
I'm just getting the hang of OOP and have been playing around with Java a lot. One of the troubles I have is deciding whether I need a private instance field for a particular class. Is there a rule of thumb I should be using in terms of whether I need to make something a private instance field of not?
Thanks.
Well, ask yourself whether it's logically part of the state of an instance of the object. Is it something about the object which is valid for the whole lifetime of the object, or is it something which only applies during the course of a single method (in which case it should be a local variable)? Or is it actually applicable to the class itself (in which case it should be static)?
If you could give some examples where you aren't quite sure, that would help.
(Note that I've assumed that the choice here is the kind of variable - static, instance or local. Instance variables should pretty much always be private :)
If it´s a natural part of the object or something the object needs to perform some task on a regular basis then by all means make it an attribute. If it is a constant then you should make it a public class variable (or rather a constant :P). That is, declare it "public static final w/e"
Public instance variables are not used as often because it often leads to messier code. Think as previously stated of the instance variables (or attributes) as the objects state. It´s usualy clearer to change the objects state by performing operations on it rather than juggle publics around. Good luck.
"Avoid public fields except for constants. (Many of the examples in the tutorial use public fields. This may help to illustrate some points concisely, but is not recommended for production code.) Public fields tend to link you to a particular implementation and limit your flexibility in changing your code." Controlling Access to Members of a Class
When learning object-oriented programming, think of it as a way to model real-world concepts as code. Nouns become objects; and the actions done to, on or by the nouns become methods. Instance variables are the properties of those nouns. For instance if you have a class representing a Car, slamOnTheBreaks() would be a method the Driver would call to slam on the breaks, and a Car has some number of seats inside, right? So an instance variable would be int numberOfSeats;.
Think of instance variables on a need-to-know, need-to-change basis. By making numberOfSeats public, that would allow the Driver to change the number of seats in the car, which doesn't make any sense. They only need to know how many seats the car has, which they can find out when they get in the car, or rather, calling the method public int getNumberOfSeats().
As Danny mentioned, the story is different for constants. If a value is a constant, it will remain constant for the entire duration of the program's execution, so for example if you want Driver Bob to be the only Driver for all those Car and Truck objects you create, Bob had better be a.) accessible, a.k.a. public, so he can be in every Car and Truck (assuming no inheritance between Car and Truck), and b.) unable to change.
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