I am programming a game in java, and as the question title suggestions i am using public fields in my classes. (for the time being)
From what i have seen public fields are bad and i have some understanding why. (but if someone could clarify why you should not use them, that would be appreciated)
The thing is that also from what i have seen, (and it seems logical) is that using private fields, but using getters and setters to access them is also not good as it defeats the point of using private fields in the first place.
So, my question is, what are the alternatives? or do i really have to use private fields with getters and setters?
For reference here is one of my classes, and some of its methods.
I will elaborate more if needs be.
public double health;
//The player's fields.
public String name;
public double goldCount;
public double maxWeight;
public double currentWeight;
public double maxBackPckSlts;
public double usedBackPckSlts; // The current back pack slots in use
public double maxHealth; // Maximum amount of health
public ArrayList<String> backPack = new ArrayList<String>();
//This method happens when ever the player dynamically takes damage(i.e. when it is not scripted for the player to take damage.
//Parameters will be added to make it dynamic so the player can take any spread of damage.
public void beDamaged(double damage)
{
this.health -= damage;
if (this.health < 0)
{
this.health = 0;
}
}
EDIT: For checking purposes, this is what my Weapon class looks like now: (Code sample is not working for some reason, so it does not look right.)
private final double DAMAGE;
private final double SPEED;
public Weapon(double initialDmg,double initialSpd,String startName,double initialWg)
{
DAMAGE = initialDmg;
SPEED = initialSpd;
setItemName(startName);
setItemWeight(initialWg);
}
public double getSpeed()
{
return SPEED;
}
public double getDamage()
{
return DAMAGE;
}
As you can see, as the Weapon's DAMAGE and SPEED do not need to be changed, they can be final's for the time being. (if, later in the game, i decided these values can be "Upgraded" so to speak, i may add setters then , with validation, or just make a new weapon with the upgraded values) They get set in the Weapon's constructor.
Conclusion: getters and setters are fine, as long as they are used smartly, and only used when needed. (however)
It's common to use getters and setters instead of giving other objects permission to change your fields directly. That might not make any sense when you see that 99.99% of your getters and setters don't do anything except what you could have done with direct access to the fields. But what happens when you decide that when a player is damaged beyond a point, he drops half his inventory? Or you want to restrict how many backpack slots can be used by magical items? You either have to hunt down all the places in your code where you modify the fields, or, if you used getters and setters, you make the changes entirely in the class. That's the heart of object oriented programming - that you've encapsulated "knowledge" of what an object does within the object itself, not spread it out among all the objects that interact with that object.
One of the core concepts of object-oriented programming is encapsulation -- that is, hiding an object's state (for example, the data in the object) from the outside, and letting the object handle it's own state.
When encapsulation is done well, the object's state can only be affected from the outside world through the interfaces provided by the object, such as methods the object has.
I think your code is already starting to use encapsulation.
Let's take a look at the code
Let's take a look at the beDamaged method.
public void beDamaged(double damage)
{
this.health -= damage;
if (this.health < 0)
{
this.health = 0;
}
}
Here's we can see that this method will be called by the outside world, and the player's health will be affected. It also contains logic, so the health cannot be a negative number. The player's beDamaged method that you wrote is keeping the state of the object within the parameters that you defined as being the valid state.
Let's infer something about the player
Now, from the above, I think I can infer the following about the player object:
A player's health cannot be a negative number.
Is what we inferred always true?
Let's see if this can always be true from the code you've provided.
Aha! We have a little problem here:
public double health;
With the health field being public, the outside world can directly manipulate the field in order to place the player object's state into one that is probably not desired, by some code like the following:
Player player = new Player();
player.health = -100
I'm going to guess that the player shouldn't be in a state where the health is a negative number.
What can we do about it?
How could that have been avoided? -- by having the health field private.
Now, the only way to affect the player's health would be through the beDamaged and gainHealth methods, and that's probably the right way for the outside world to affect your player's health.
Which also means this -- when you make a field private, that does not automatically mean that you should make getters and setters for the field.
Private fields does not necessitate getters and setters
Getters and setters are usually a way to directly affect a field that an object has, maybe with some validation to prevent bad input from making your object have a state that it shouldn't, but there are going to be times where the object itself should be in charge of affecting the data, rather than an outside entity.
In Java, using private fields with getters/setters is the recommend practice, provided external clients of your class really need access to those fields.
Otherwise keep them as private fields and simply don't provide a getter/setter.
There are various reasons why this is a best practice:
If clients are using your field directly and later something needs to change regarding that, you're stuck. With a getter you can do a whole lot of things before the field is accessed.
There is something called the JavaBeans specification that requires you to use getter/setters. Without them your class (then called bean) won't interoperate with that. JSP and JSF's EL is one example of something that required your class to comply with JavaBeans standards.
(p.s. unrelated to your question, but you'd better not declare backPack as an ArrayList. Declare as List; code to interface, not to implementation)
If you have a private field with a method get() and a method set() that don't do anything other than retrieve and assign the value, you should just make the field public, as the field isn't really private, and the getters and setters only hurt performance. If the getters and setters check the value being set or if the value is allowed to retrieve, then go ahead and use getters and setters. e.g. If you have a variable private int width; and someone tries to put in -1 with a setter, and the setter makes sure it isn't negative, then that is a good use. For example:
private int width;
public int get(){
return width;
}
public void set(int w){
if (w < 0) throw new RuntimeException();
else width = w;
}
This would be a good use of getters and setters. Otherwise, they hurt your performance if the only thing they do is assign or get the value without anything else.
So to make a long story short:
Use getters and setters when doing anything other than retrieving or assigning a value. Else, just use public fields.
i.e.
BAD:
private int width;
public int get(){
return width;
}
public void set(int w){
width = w;
}
GOOD:
private int width;
public int get(){
return width;
}
public void set(int w){
if (w < 0) throw new RuntimeException();
else width = w;
}
GOOD if you don't want anything other than getting or setting:
public int width;
About this:
The thing is that also from what i have seen, (and it seems logical) is that using private fields, but using getters and setters to access them is also not good as it defeats the point of using private fields in the first place.
The main problem is that many developers automatically generate getters and setters for all private fields. And if you're going to do that, I agree, you might as well keep the field public (no, public fields are even worse).
For every field that you have, you should check:
a) does it need a Getter (do other classes need to know the value of this field)
b) does it need a Setter (do other classes need to be able to change the value of this field)
c) or does the field need to be immutable (final), if so it must be initialized during definition or in the constructor (and it can obviously have no setter)
But you should hardly ever (exception: value objects) assume that all private fields will have getters and setters and let your IDE generate them all.
An advantage of using getters and especially setters is, that it is much easier to debug write access to the fields.
private fields and setters and getters is indeed your best way to go.
Further note that this is in general good code in any language as it keeps your security nice and tight while also giving you a structure that is far easier to debug and maintain. (Don't forget to document btw!)
All in all, go with setters and getters, it's just good practice even if you find options.
Getters and setters are part of the public interface of your class. It's a contract between the class designer/developer and the users of that class. When you define getters and setters, you should be committed to maintain them in future versions.
Attributes should only correspond the implementation of a given version of the class. In this way, the class developer may unilaterally change the implementation, hence the field, without breaking his/her commitment to maintain the interfaces.
Here is an example. Consider a class called Point. If you decide that a Point has x and y public attributes, then you may never change this. In contrast, if you have get/set X/Y methods, subsequent versions of the class may use various internal representations: rectangular coordinates (x, y), but also polar (r, theta), etc. All this without modifying the public interface.
A shorter version of your methods...
public void beDamaged(double damage) {
health = Math.max(0, health-damage);
}
public void gainHealth(double gainedHp) {
health = Math.min(maxHealth, health + gainedHp);
}
or even the following which can be called with +1 to gain, -1 to lose 1 hp.
public void adjustHealth(double adjustHp) {
health = Math.max(0, Math.min(maxHealth, health + adjustHp));
}
If you're not maintaining any invariants, then public fields are the way to go. If you do need an invariant across multiple members, then you need private fields and encapsulation.
But if you can't come up with any better names than GetFoo and SetFoo for the methods, it's a good clue that your getters and setters are probably worthless.
.... pathetic content omitted....
EDIT
sorry for beeing a little too pathetic -must be the pills... The other answers are quite relevant and good
One advantage not yet mentioned for avoiding public fields: if there aren't any public fields, one may define an interface that includes all the public features of the class, have the class implement that interface, and then have everyplace that uses the class use the interface instead. If that is done, one may later design a class which has completely different methods and fields, but which implements the same interface, and use that class interchangeably with the original. If this is done, it may be useful to have the class implement a static factory method in addition to the constructor, and have the factory return an object of the interface type. Doing that would allow later versions of the factory to return an object of some other type. For example, one may come up with a low-cost version of the object in which many properties return constants; the factory could see if such an object would be suitable, and if so return one instead of the normal object.
Incidentally, the concept of using a mixture of constant and mutable objects in an adventure goes back at least to 1980. In Warren Robinett's "Adventure" cartridge for the 2600, each object has a number of pointers stored in ROM for things like position and state, so objects which aren't going to move (such as the castle gates or the "signature") don't need to have their position stored in RAM, and most grabbable objects (which don't have any state other than their position) won't need to store a state in RAM, but animated objects like the dragons and bat can store both state and position in RAM. On a machine with 128 bytes of RAM total, such savings were critical.
Related
If I am extending a class that has its own protected member variables and methods, then in the subclass (or the class doing the extending, whichever is right), how do I correctly refer to these things?
For example if I have protected int mInt in the extended class, do I make another int mInt in the subclass and initialize that as well? Or do I always refer to the parent class' fields and methods directly?
I ask because I need to ensure that certain objects have certain fields, so I need them to all extend the same parent class, but I don't know what this means in terms of how to structure the methods in the subclasses. Do I just use super all the time or is it a good idea to make "local" copies of all the parent contents as well?
Protected methods are part of the API of the class, their use is similar to public methods, but their visibility is restricted to subclasses, which is sometimes useful.
Protected fields on the other hand are almost never a good idea, as they make it impossible for a class to maintain its invariants. Take this example:
class Divider {
protected int divisor;
public void setDivisor(int divisor) {
//we need to check the input to make sure our Divider works correctly
if (divisor == 0)
throw new IllegalArgumentException("divisor can't be zero");
this.divisor = divisor;
}
public int divide(int number) {
return number/divisor;
}
}
So far, so good, however along comes another class:
class BadDivider extends Divider {
public void doABadThing() {
this.divisor = 0;
}
}
Now we're in a bad situation: all the effort to maintain our class invariant (i.e. divisor != 0) was ruined by BadDivider. Since anyone can extend Divider, there's no way to stop this happening. This also tells us when it is sort of okay to use protected fields: when you can guarantee that you control all the classes that can inherit them. This very rarely happens.
So the solution is to keep every field private and make sure that you check the inputs of your methods (and your constructors). This allows you to reason about the internal state of your objects, and guarantee that they're always in a valid state.
I would always use private attributes; not have a setter unless really needed; have an interface if you need to expose a class member.
That being said, you would inherit class members. You can refer super if not accessible from child and you do not need to create another mInt int in subclass; if you need to set the value in subclass, you have a protected setter in parent and use in subclass/class. I would advise reading Design Patterns and 4 core OO principles. Hope helps.
I try to understand a lot of times but I failed to understand this.
Encapsulation is the technique of making the fields in a class private
and providing access to the fields via public methods. If a field is
declared private, it cannot be accessed by anyone outside the class,
thereby hiding the fields within the class.
How can we change the values of fields through setter methods? How do we prevent accessing the fields directly? What is the real use of encapsulation?
Assume you have an age property.
The user can enter a value of -10, which although is a valid number, is an invalid age. A setter method could have logic which would allow you to catch such things.
Another scenario, would be to have the age field, but hide it. You could also have a Date of Birth field, and in it's setter you would have something like so:
...
private int age
private Date dob
...
public void setDateOfBirth(Date dob)
{
this.dob = dob;
age = ... //some logic to calculate the age from the Date of Birth.
}
I have also been confused like you too for a long time until I read the book Encapsulation and Inheritance in Object-Oriented Programming Language and a website that explained the importance of Encapsulation. I was actually directed from the website to the book.
People always say encapsulation is "hiding of information" therefore, maybe, making encapsulation focus on security as the main use. Yes you are hiding information in practice, but that should not be the definition as it could confuse people.
Encapsulation is simply "minimizing inter-dependencies among separately-written modules by defining strict external interfaces" (quoting from the book). That is to say that when I am building a module, I want a strict contract between my clients and me on how they can access my module. Reason being that, I can improve the inner workings without it AFFECTING my client's, life, application or whatever they are using my module for. Because their "module" does not exactly depend on the Inner workings of my module but depends on the "external interface", I made available to them.
So, if I don't provide my client with a setter and give them direct access to a variable, and I realize that I need to set some restriction on the variable before my client could use it, me changing it, could be me, changing the life of my client, or application of my client with HUGE EXPENSE. But if I provided the "strict contract" by creating a "strict external interface" i.e setter, then I can easily change my inner workings with very little or no expense to my clients.
In the setter situation (using encapsulation), if it happens that when you set a variable, and I return a message informing you that it has been assigned, now I could send a message via my "interface", informing my client of the new way my module have to be interacted with, i.e "You cannot assign negative numbers" that is if my clients try to assign negative number. But if I did not use encapsulation, and gave my client direct access to a variable and I do my changes, it could result in a crashed system. Because if the restriction I implemented, is that, you could not save negatives and my client have always been able to store negatives, my clients will have a crashed system in their hands (if that "crashed system" was a banking system, imagine what could happen).
So, encapsulation is more about reducing dependency between module, and an improvement can be made "quietly" with little or no expense to other modules interacting with it, than it is of security. Because the interacting modules depend on the "strict external interface or strict contract".
I hope this explains it properly. If not you could go the links below and read for yourself.
encapsulation matters
Encapsulation and Inheritance in Object-Oriented Programming Languages
The real use of encapsulation is also in the fact that you can do additional checks/processing on the way the values are set.
You're not exactly preventing access to the fields -- you're controlling how others can access certain fields. For example you can add validation to your setter method, or you can also update some other dependent field when the setter method of a field is called.
You can prevent write or read access to the field (e.g. by only providing a getter or setter respectively) -- but encapsulation with properties allows you to do more than just that.
If you have private fields they can't be accessed outside the class, that means basically those fields don't exist to the outside world and yes you can change their value through setter methods but using setter methods you have more flexibility/control to say who gets to change the fields and to what value can they be changed to...basically with encapsulation you get to put restrictions on how and who changes your fields.
For example you have: private double salary, you setter method could restrict that only hr staff can change the salary field it could be written as:
void setSalary(Person p,double newSalary)
{
//only HR objects have access to change salary field.
If(p instanceof HR && newSalary>=0)
//change salary.
else
S.o.p("access denied");
}
Imagine if salary was public and could be access directly any can change it however and whenever they want, this basically the significance of encapsulation
The main idea behind encapsulation is data hiding. There are several reasons why we use encapsulation in object oriented programming. Some of the identified reasons for why we encapsulation are as follows (The real use of encapsulation).
Better maintainability: When all the properties are private and encapsulated, it is easy for us to maintain the program simply by changing the methods.
Make Debugging Easy: This is in line with the above point. We know that the object can only be manipulated through methods. So, this makes it easy to debug and catch bugs.
Have a Controlled Environment: Let the users use the given objects, in a controlled manner, through objects.
Hide Complexities: Hiding the complexities irrelevant to the users. Sometimes, some properties and methods are only for internal use and the user doesn't have to know about these. This makes is simple for the user to use the object.
So, to answer the question, "What is the use of encapsulation when I'm able to change the property values with setter methods?", given above are some of the main reasons why we use encapsulation. To provide an understanding on why, getters and setters are useful, given below are some important points, obtained from this article.
You can limit the values that can be stored in a field (i.e. gender must be F or M).
You can take actions when the field is modified (trigger event, validate, etc).
You can provide thread safety by synchronizing the method.
You can switch to a new data representation (i.e. calculated fields, different data type)
Any how i am able to change the values of fields through setter methods.
Only if the setter method lets you do that.
How we are preventing the accessing fields?
The setter and getter get to control if and how you can access the fields.
A setter may check if the value is valid. It may ask a SecurityManager if you should be allowed to do this. It may convert between data types. And so on.
Lets suppose you make a custom Date class with the following setters / getters:
getDay()
getMonth()
getYear()
setDay()
setMonth()
setYear()
Internally you could store the date using:
private int day;
private int month;
private int year;
Or you could store the date using a java.lang.Date-object:
private Date date;
Encapsulation doesn't expose how your class is working internally. It gives you more freedom to change how your class works. It gives you the option to control the access to your class. You can check if what the user enters is valid (you don't want the user to enter a day with a value of 32).
It's aim is nothing but protecting anything which is prone to change. You have plenty of examples on the web, so I give you some of the advantages of it:
Encapsulated Code is more flexible and easy to change with new requirements
Allows you to control who can access what. (!!!)
Helps to write immutable class in Java
It allows you to change one part of code without affecting other part of code.
Accessing fields thru methods make difference because it makes it OOP. Eg you can extend you class and change the behaviour which you cannot do with direct access. If you have getters / setters you can make a proxy of your class and do some AOP or a make a 1.4 dynamic proxy. You can make a mock from your class and make unit testing...
Encapsultaion is used for hiding the member variables ,by making member as private and access that member variable by getter and setter methods.
Example
class Encapsulation{
private int value ;
Encapsulation() {
System.out.println("constructor calling ");
}
void setValue(int value){
this.value = value;
}
int getValue() {
return value;
}
}
class EncapsulationMain {
public static void main(String args[]) {
Encapsulation obj = new Encapsulation();
obj.setValue(4);
//System.out.print("value is "+obj.value);
//obj.value = 55;
//System.out.print("obj changing the value"+obj.value);
System.out.print("calling the value through the getterMethod"+obj.getValue());
}
}
you cannot access the private value outside the class.
Well, encapsulation is not all about hiding data. It is all about getting control over what is stored in the fields. Using encapsulation we can make a field as read-only or write-only depending upon the requirements.Also the users don't know how the data is stored in the fields. We can use some special encryption in the setter methods and store it in the fields.
For example human is a object. We only require the name field of the human to be read by the user but not to be modified. Then we define only get method on the name field.This is how the encapsulation is useful.
If you have class all of its properties are private-meaning that they cannot be accessed from outside the class- and the only way to interact with class properties is through its public methods.
You are changing tha values by giving the public access to those methods(setters).
using encapsulation the fields of a class can be made read-only or write-only.
Instead of letting everyone access the variables directly:
public Object object;
Is better to use SET and GET methods, or for example just the GET method (Sometimes you dont want nobody to set other value to that variable).
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
By using encapsulation you separate your class from the out-side world (other classes) and out-side world can access and modify your class instance variables through access modifiers, which provides several benefits:
-You can do some logging in your getter/setter methods.
-You can validate /normalize (for example trim spaces, remove special character,...) Your input in setter method.
And also you can hide your implementation from the outside world, for example you have a collection like array list in your class and you write your getter method like this
public List<t> get collection(){
return new ArrayList<t>(this.arrayList);
}
So in this case, in the future if you decide to change your implementation of collection from array list to something else like linked list, you are free to do so because out side world doesn't know anything about your implementation.
Encapsulation is not about secrecy, it is about reducing dependency over separate part of the application.
We control dependency (loose / weak / low coupling) by hiding information over separate part of the application.
Adding to Uche Dim's answer, look at the following example:
Two Connections:
public class Area {
// fields to calculate area
private int length;
private int breadth;
// constructor to initialize values
Area(int length, int breadth) {
this.length = length;
this.breadth = breadth;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getBreadth() {
return breadth;
}
public void setBreadth(int breadth) {
this.breadth = breadth;
}
public int getArea() {
int area = length * breadth;
return area;
}
}
class Main {
public static void main(String[] args) {
Area rectangle = new Area(5, 6);
// Two Connections
int length = rectangle.getLength();
int breadth = rectangle.getBreadth();
int area = length * breadth;
System.out.println("Area: " + area);
}
}
Please note that in the Main class, we are calling two methods (getLength() and getBreadth()) of Area class.
One Connection:
public class Area {
// fields to calculate area
private int length;
private int breadth;
// constructor to initialize values
Area(int length, int breadth) {
this.length = length;
this.breadth = breadth;
}
public int getArea() {
int area = length * breadth;
return area;
}
}
class Main {
public static void main(String[] args) {
Area rectangle = new Area(5, 6);
// One Connection
int area = rectangle.getArea();
System.out.println("Area: " + area);
}
}
Here, in the Main class, we are calling one methods (getArea()) of Area class.
So in the second example, the connection is weaker than the previous one (first one calling two methods or the Area class, second one calling one method of the Area class). Given, less connection (lower / weaker coupling) is better, the second example is better.
We should always keep fields and methods private unless necessary. In the Two Connections example, we made the mistake of creating the getters unnecessarily. As we have created it, the IntelliJ Idea (auto suggestion of modern IDE) suggested the developer who was working on the Main class that you can use the getLength() and getBreadth() methods and he did. He did not inquire further to check if there was a getArea() method. As a result he created stronger coupling than necessary.
We should not unnecessarily create getters. We should not unnecessarily make fields public or protected. If you must, first try protected, if that does not work then make it public. That way we will have a lesser possibility of having a tighter coupling.
If you still have the question "what is the difference between making a field public compared to making a field private but it's getters public?", in other words "Why should we use a function to get a value instead of getting it directly?" Well it gives you another layer of abstraction. For example, if you need some extra processing of the data before receiving it (ex. validation), you can do it there. Moreover, once you expose internals of a class, you can not change that internal representation or make it better until making changes in all client codes.
For example, suppose you did something like:
public class Area {
private int length;
private int breadth;
}
class Main {
public static void main(String[] args) {
Area rectangle = new Area(5, 6);
int area = rectangle.length * rectangle.breadth;
System.out.println("Area: " + area);
}
}
Now, if you want to change breadth to width in Area class, you can not do it without breaking the program, unless you search and replace rectangle.breadth with rectangle.width in all the clients where rectangle.breadth was used (in this case Main class).
There are other benefits as well. For example, Member variables cannot be overridden like methods. If a class has getters and setters, it's subclass can override these methods and return what makes more sense in the context of subclass.
Please check Why getter and setter are better than public fields in Java? for more details.
P.S. These are trivial examples, but in large scale, when program grows and frequent change requests are a reality, this makes sense.
I'm OK with using get and set, to mask and make reengineering easier, but if you tell to a novice programmer that using get and set does encapsulation, as I've seen many times, they will use set and get for internal members initialized by the constructor.
And this 99.9 % is wrong!!!!!
private uint8_t myvar = 0;
setMyVar(uint8_t value){
this.myvar = value * (20 / 41);
}
uint8_t getMyVar(){
return this. myvar ;
}
That’s for me is ok, but I think encapsulation is a method first, rather than get and set.
My inglish is not very well,but I think that this article says something like this.
Iam a Java beginner and i would like to ask whats the pros and cons about this:
If i make a Class and i wont write my own setters and getters i can just get and set my class's properties like:
myClassInstance.name = "Jones"
myClassInstance.job = "Manager"
System.out.println(myClassInstance.name);
System.out.println(myClassInstance.job);
Why better if i make getters and setters and do like this:
myClassInstance.setName("Jones");
myClassInstance.setJob("Manager");
System.out.println(myClassInstance.getName());
System.out.println(myClassInstance.getJob());
This question is related to one of the basic principals of OO design: Encapsulation!
Accessors (also known as getters and setters) are methods that let you read and write the value of an instance variable of an object
public class AccessorExample {
private String attribute;
public String getAttribute() {
return attribute;
}
public void setAttribute(String attribute) {
this.attribute = attribute;
}
}
Why to use them?
Getter and Setters make APIs more stable. Lets consider a field public in a class which is accessed by other classes. Now later on, you want to add any extra logic while getting and setting the variable. This will impact the existing client that uses the API. So any changes to this public field will require change to each class that refers it. On the contrary, with accessor methods, one can easily add some logic like cache some data, lazily initialize it later. Moreover, one can fire a property changed event if the new value is different from the previous value. All this will be seamless to the class that gets value using accessor method.
Also Getters and setters methods allow different access levels - for eg. Get may be public, but the Set could be protected.
directly accessing the fields will lead to voilation of encapsulation.
making public variables to access them will be difficult to manage the state of that object.
where as with methods you can easily control state of the object.
Using getters and setters instead of public members is called encapsulation, and is a fundamental OOP concept. This way you are able to control the input and keep some sort of logic and validity to your models.
class Bottle {
public int volume = 0;
}
class EncapsulatedBottle {
private int volume = 0;
public void setVolume(int volume) throws Exception {
if (volume < 1) {
throw new Exception("A bottle cannot have a negative volume");
}
this.volume = volume;
}
public int getVolume() {
return this.volume;
}
}
Spot the difference :-)
Using getters and setters gives you more control over the validity of your objects, giving you the option of testing values that are set to ensure that they are reasonable, etc. (And of course, for read-only properties, you just leave off the setter.) On a modern JVM with a just-in-time compiler, they essentially don't cost anything; if they're really just reading and writing to a private data member, and if they're in a hotspot (bit of code that gets used a lot), the JIT will inline them.
Using getters/setters is normally better, because:
you can restrict (public) access to readonly (no setter)
you can add additional code without having to recompile/change the users of the property (i.e. classes that call the getter/setter)
it complies with the Java Bean specification which states a property must have getters/setters - and many libraries/frameworks, like Java EL etc. rely on that contract
How can we have a variable that is writable within the class but only "readable" outside it?
For example, instead of having to do this:
Class C {
private int width, height;
int GetWidth(){
return width;
}
int GetHeight(){
return height;
}
// etc..
I would like to do something like this:
Class C {
public_readonly int width, height;
// etc...
What's the best solution?
Create a class with public final fields. Provide constructor where those fields would be initialized. This way your class will be immutable, but you won't have an overhead on accessing the values from the outside. For example:
public class ShortCalendar
{
public final int year, month, day;
public ShortCalendar(Calendar calendar)
{
if (null == calendar)
throw new IllegalArgumentException();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DATE);
}
}
There's no way to do this in Java.
Your two options (one which you mentioned) are using public getters and making the field private, or thorough documentation in the class.
The overhead on getter methods in extremely small (if at all). If you're doing it a large number of times, you might want to cache the fetched value instead of calling the get method.
EDIT:
One way to do it, although it has even more overhead than the getter, is defining a public inner class (let's call it innerC) with a constructor that is only available to your C class, and make your fields public. That way, you can't create innerC instances outside your class so changing your fields from outside is impossible, yet you can change them from inside. You could however read them from the outside.
from what I know the compiler does not optimize this kind of code
The Hotspot JIT compiler most definitely does.
I was wondering what's the best solution?
Stop optimizing prematurely. If you're using this code in a painting routine, I can guarantee that the actual painting will take at least a hundred times longer than calling a trivial method, even if it's not inlined.
there is no way to make a field "read only" from outside. the only - and right - way is to make the fields private and provide only getters, no setters.
Actually the HotSpot compiler would most likely inline calls to your getters, so no overhead will be involved (besides, the overhead for calling these methods would hardly be measurable).
EDIT
If you really need every CPU cycle, use C or C++ (or write performance-critical parts in it and call it via JNA, though its unlikely that it will be worth the time spent).
Your solution is:
private fields,
private setters,
protected or public getters (note: protected allows access from same package as well as from subclasses)
yes.. we can make a variable read-only using final keyword
Ex: public final int id = 10;
In my code, I am creating a collection of objects which will be accessed by various threads in a fashion that is only safe if the objects are immutable. When an attempt is made to insert a new object into my collection, I want to test to see if it is immutable (if not, I'll throw an exception).
One thing I can do is to check a few well-known immutable types:
private static final Set<Class> knownImmutables = new HashSet<Class>(Arrays.asList(
String.class, Byte.class, Short.class, Integer.class, Long.class,
Float.class, Double.class, Boolean.class, BigInteger.class, BigDecimal.class
));
...
public static boolean isImmutable(Object o) {
return knownImmutables.contains(o.getClass());
}
This actually gets me 90% of the way, but sometimes my users will want to create simple immutable types of their own:
public class ImmutableRectangle {
private final int width;
private final int height;
public ImmutableRectangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() { return width; }
public int getHeight() { return height; }
}
Is there some way (perhaps using reflection) that I could reliably detect whether a class is immutable? False positives (thinking it's immutable when it isn't) are not acceptable but false negatives (thinking it's mutable when it isn't) are.
Edited to add: Thanks for the insightful and helpful answers. As some of the answers pointed out, I neglected to define my security objectives. The threat here is clueless developers -- this is a piece of framework code that will be used by large numbers of people who know next-to-nothing about threading and won't be reading the documentation. I do NOT need to defend against malicious developers -- anyone clever enough to mutate a String or perform other shenanigans will also be smart enough to know it's not safe in this case. Static analysis of the codebase IS an option, so long as it is automated, but code reviews cannot be counted on because there is no guarantee every review will have threading-savvy reviewers.
There is no reliable way to detect if a class is immutable. This is because there are so many ways a property of a class might be altered and you can't detect all of them via reflection.
The only way to get close to this is:
Only allow final properties of types that are immutable (primitive types and classes you know are immutable),
Require the class to be final itself
Require that they inherit from a base class you provide (which is guaranteed to be immutable)
Then you can check with the following code if the object you have is immutable:
static boolean isImmutable(Object obj) {
Class<?> objClass = obj.getClass();
// Class of the object must be a direct child class of the required class
Class<?> superClass = objClass.getSuperclass();
if (!Immutable.class.equals(superClass)) {
return false;
}
// Class must be final
if (!Modifier.isFinal(objClass.getModifiers())) {
return false;
}
// Check all fields defined in the class for type and if they are final
Field[] objFields = objClass.getDeclaredFields();
for (int i = 0; i < objFields.length; i++) {
if (!Modifier.isFinal(objFields[i].getModifiers())
|| !isValidFieldType(objFields[i].getType())) {
return false;
}
}
// Lets hope we didn't forget something
return true;
}
static boolean isValidFieldType(Class<?> type) {
// Check for all allowed property types...
return type.isPrimitive() || String.class.equals(type);
}
Update: As suggested in the comments, it could be extended to recurse on the superclass instead of checking for a certain class. It was also suggested to recursively use isImmutable in the isValidFieldType Method. This could probably work and I have also done some testing. But this is not trivial. You can't just check all field types with a call to isImmutable, because String already fails this test (its field hash is not final!). Also you are easily running into endless recursions, causing StackOverflowErrors ;) Other problems might be caused by generics, where you also have to check their types for immutablity.
I think with some work, these potential problems might be solved somehow. But then, you have to ask yourself first if it really is worth it (also performance wise).
Use the Immutable annotation from Java Concurrency in Practice. The tool FindBugs can then help in detecting classes which are mutable but shouldn't be.
At my company we've defined an Attribute called #Immutable. If you choose to attach that to a class, it means you promise you're immutable.
It works for documentation, and in your case it would work as a filter.
Of course you're still depending on the author keeping his word about being immutable, but since the author explicitly added the annotation it's a reasonable assumption.
Basically no.
You could build a giant white-list of accepted classes but I think the less crazy way would be to just write in the documentation for the collection that everything that goes is this collection must be immutable.
Edit: Other people have suggested having an immutable annotation. This is fine, but you need the documentation as well. Otherwise people will just think "if I put this annotation on my class I can store it in the collection" and will just chuck it on anything, immutable and mutable classes alike. In fact, I would be wary of having an immutable annotation just in case people think that annotation makes their class immutable.
In my code, I am creating a collection of objects which will be accessed by various threads in a fashion that is only safe if the objects are immutable.
Not a direct answer to your question, but keep in mind that objects that are immutable are not automatically guaranteed to be thread safe (sadly). Code needs to be side-effect free to be thread safe, and that's quite a bit more difficult.
Suppose you have this class:
class Foo {
final String x;
final Integer y;
...
public bar() {
Singleton.getInstance().foolAround();
}
}
Then the foolAround() method might include some non-thread safe operations, which will blow up your app. And it's not possible to test for this using reflection, as the actual reference can only be found in the method body, not in the fields or exposed interface.
Other than that, the others are correct: you can scan for all declared fields of the class, check if every one of them is final and also an immutable class, and you're done. I don't think methods being final is a requirement.
Also, be careful about recursively checking dependent fields for immutability, you might end up with circles:
class A {
final B b; // might be immutable...
}
class B {
final A a; // same so here.
}
Classes A and B are perfectly immutable (and possibly even usable through some reflection hacks), but naive recursive code will go into an endless loop checking A, then B, then A again, onwards to B, ...
You can fix that with a 'seen' map that disallows cycles, or with some really clever code that decides classes are immutable if all their dependees are immutable only depending on themselves, but that's going to be really complicated...
This could be another hint:
If the class has no setters then it cannot be mutated, granted the parameters it was created with are either "primitive" types or not mutable themselves.
Also no methods could be overridden, all fields are final and private,
I'll try to code something tomorrow for you, but Simon's code using reflection looks pretty good.
In the mean time try to grab a copy of the "Effective Java" book by Josh Block, it has an Item related to this topic. While is does not for sure say how to detect an immutable class, it shows how to create a good one.
The item is called: "Favor immutability"
Updated link: https://www.amazon.com/Effective-Java-Joshua-Bloch/dp/0134685997
You Can Ask your clients to add metadata (annotations) and check them at runtime with reflection, like this:
Metadata:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.CLASS)
public #interface Immutable{ }
Client Code:
#Immutable
public class ImmutableRectangle {
private final int width;
private final int height;
public ImmutableRectangle(int width, int height) {
this.width = width;
this.height = height;
}
public int getWidth() { return width; }
public int getHeight() { return height; }
}
Then by using reflection on the class, check if it has the annotation (I would paste the code but its boilerplate and can be found easily online)
why do all the recommendations require the class to be final? if you are using reflection to check the class of each object, and you can determine programmatically that that class is immutable (immutable, final fields), then you don't need to require that the class itself is final.
You can use AOP and #Immutable annotation from jcabi-aspects:
#Immutable
public class Foo {
private String data;
}
// this line will throw a runtime exception since class Foo
// is actually mutable, despite the annotation
Object object = new Foo();
Like the other answerers already said, IMHO there is no reliable way to find out if an object is really immutable.
I would just introduce an interface "Immutable" to check against when appending. This works as a hint that only immutable objects should be inserted for whatever reason you're doing it.
interface Immutable {}
class MyImmutable implements Immutable{...}
public void add(Object o) {
if (!(o instanceof Immutable) && !checkIsImmutableBasePrimitive(o))
throw new IllegalArgumentException("o is not immutable!");
...
}
Try this:
public static boolean isImmutable(Object object){
if (object instanceof Number) { // Numbers are immutable
if (object instanceof AtomicInteger) {
// AtomicIntegers are mutable
} else if (object instanceof AtomicLong) {
// AtomLongs are mutable
} else {
return true;
}
} else if (object instanceof String) { // Strings are immutable
return true;
} else if (object instanceof Character) { // Characters are immutable
return true;
} else if (object instanceof Class) { // Classes are immutable
return true;
}
Class<?> objClass = object.getClass();
// Class must be final
if (!Modifier.isFinal(objClass.getModifiers())) {
return false;
}
// Check all fields defined in the class for type and if they are final
Field[] objFields = objClass.getDeclaredFields();
for (int i = 0; i < objFields.length; i++) {
if (!Modifier.isFinal(objFields[i].getModifiers())
|| !isImmutable(objFields[i].getType())) {
return false;
}
}
// Lets hope we didn't forget something
return true;
}
To my knowledge, there is no way to identify immutable objects that is 100% correct. However, I have written a library to get you closer. It performs analysis of bytecode of a class to determine if it is immutable or not, and can execute at runtime. It is on the strict side, so it also allows whitelisting known immutable classes.
You can check it out at: www.mutabilitydetector.org
It allows you to write code like this in your application:
/*
* Request an analysis of the runtime class, to discover if this
* instance will be immutable or not.
*/
AnalysisResult result = analysisSession.resultFor(dottedClassName);
if (result.isImmutable.equals(IMMUTABLE)) {
/*
* rest safe in the knowledge the class is
* immutable, share across threads with joyful abandon
*/
} else if (result.isImmutable.equals(NOT_IMMUTABLE)) {
/*
* be careful here: make defensive copies,
* don't publish the reference,
* read Java Concurrency In Practice right away!
*/
}
It is free and open source under the Apache 2.0 license.
Something which works for a high percentage of builtin classes is test for instanceof Comparable. For the classes which are not immutable like Date, they are often treated as immutable in most cases.
I appreciate and admire the amount of work Grundlefleck has put into his mutability detector, but I think it is a bit of an overkill. You can write a simple but practically very adequate (that is, pragmatic) detector as follows:
(note: this is a copy of my comment here: https://stackoverflow.com/a/28111150/773113)
First of all, you are not going to be just writing a method which determines whether a class is immutable; instead, you will need to write an immutability detector class, because it is going to have to maintain some state. The state of the detector will be the detected immutability of all classes which it has examined so far. This is not only useful for performance, but it is actually necessary because a class may contain a circular reference, which would cause a simplistic immutability detector to fall into infinite recursion.
The immutability of a class has four possible values: Unknown, Mutable, Immutable, and Calculating. You will probably want to have a map which associates each class that you have encountered so far to an immutability value. Of course, Unknown does not actually need to be implemented, since it will be the implied state of any class which is not yet in the map.
So, when you begin examining a class, you associate it with a Calculating value in the map, and when you are done, you replace Calculating with either Immutable or Mutable.
For each class, you only need to check the field members, not the code. The idea of checking bytecode is rather misguided.
First of all, you should not check whether a class is final; The finality of a class does not affect its immutability. Instead, a method which expects an immutable parameter should first of all invoke the immutability detector to assert the immutability of the class of the actual object that was passed. This test can be omitted if the type of the parameter is a final class, so finality is good for performance, but strictly speaking not necessary. Also, as you will see further down, a field whose type is of a non-final class will cause the declaring class to be considered as mutable, but still, that's a problem of the declaring class, not the problem of the non-final immutable member class. It is perfectly fine to have a tall hierarchy of immutable classes, in which all the non-leaf nodes must of course be non-final.
You should not check whether a field is private; it is perfectly fine for a class to have a public field, and the visibility of the field does not affect the immutability of the declaring class in any way, shape, or form. You only need to check whether the field is final and its type is immutable.
When examining a class, what you want to do first of all is to recurse to determine the immutability of its super class. If the super is mutable, then the descendant is by definition mutable too.
Then, you only need to check the declared fields of the class, not all fields.
If a field is non-final, then your class is mutable.
If a field is final, but the type of the field is mutable, then your class is mutable. (Arrays are by definition mutable.)
If a field is final, and the type of the field is Calculating, then ignore it and proceed to the next field. If all fields are either immutable or Calculating, then your class is immutable.
If the type of the field is an interface, or an abstract class, or a non-final class, then it is to be considered as mutable, since you have absolutely no control over what the actual implementation may do. This might seem like an insurmountable problem, because it means that wrapping a modifiable collection inside an UnmodifiableCollection will still fail the immutability test, but it is actually fine, and it can be handled with the following workaround.
Some classes may contain non-final fields and still be effectively immutable. An example of this is the String class. Other classes which fall into this category are classes which contain non-final members purely for performance monitoring purposes (invocation counters, etc.), classes which implement popsicle immutability (look it up), and classes which contain members that are interfaces which are known to not cause any side effects. Also, if a class contains bona fide mutable fields but promises not to take them into account when computing hashCode() and equals(), then the class is of course unsafe when it comes to multi-threading, but it can still be considered as immutable for the purpose of using it as a key in a map. So, all these cases can be handled in one of two ways:
Manually adding classes (and interfaces) to your immutability detector. If you know that a certain class is effectively immutable despite the fact that the immutability test for it fails, you can manually add an entry to your detector which associates it with Immutable. This way, the detector will never attempt to check whether it is immutable, it will always just say 'yes, it is.'
Introducing an #ImmutabilityOverride annotation. Your immutability detector can check for the presence of this annotation on a field, and if present, it may treat the field as immutable despite the fact that the field may be non-final or its type may be mutable. The detector may also check for the presence of this annotation on the class, thus treating the class as immutable without even bothering to check its fields.
I hope this helps future generations.