Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should an immutable class member have an accessor method or allowed to be public?

I have a question about best design practices. I have been attempting to build more immutable components into my project because I read they were easier to maintain in the long run and wanted to test this.

When you have a class with immutable data members, say

 public/private final int importantNumber = 3;

Should the int still be declared as private and given an accessor method, or because its finals, what is the hard in allowing direct access and making it public? I don't see any issues with it being made public because you are unable to change it.

In my case, the immutable object is created with values that are passed into it and then will self populate the others from a database, with everything being final.

Or is this merely a question of preference and will spark a religious war? As there are lots of questions about accessing the data member from inside the class, I want to make it clear that I am asking from another external class attempting to get the value.

like image 319
Fering Avatar asked Jan 30 '19 14:01

Fering


People also ask

Can immutable class have getters?

A class being immutable means that none of its internal state can change after construction. Such a class can have getters but it shouldn't have setters, because then it would be mutable rather than immutable.

Do immutable classes have Mutators?

Some classes do not contain mutator methods. Objects from these classes are said to be immutable. For example, Java's String class cannot alter the string once the object is created. The wrapper classes (e.g. Integer class and Double class) allow accessors but no mutators.

What is a disadvantage of immutable classes?

The only real disadvantage of immutable classes is that they require a separate object for each distinct value. Creating these objects can be costly, especially if they are large.

Is it mandatory to make the class final if making a custom immutable class?

No, it is not mandatory to have all properties final to create an immutable object. In immutable objects you should not allow users to modify the variables of the class. You can do this just by making variables private and not providing setter methods to modify them.


2 Answers

Making things public allows other code to rely on it.

It doesn't matter if the data is mutable or immutable. As soon as some other code makes itself dependant on that information, you enable future problems. And in any larger project, these problems will manifest themselves sooner or later.

Making things public, all of a sudden, (internal) implementation details can leak into other code! And of course: if that data is mutable, that just opens a real can of worms.

But even a simple if (someObject.someField == whatever) then do this else do that can quickly turn into a huge problem. Just assume you have that code in 10, 50, 100 different places in your huge project.

Thus, your default rule is: hide your information. Making things public is the exception, it happens because you absolutely want your design to be that way. Your default is to give your fields (and even methods) the most restrictive visibility that still allows you to implement your requirements.

And note: it is just "slightly" better to hide the field and having an accessor method for it. Because if (someObject.someMethod() == ...) leads to the same problems. And (almost) worse: now you decide that someMethod() should do something different, to solve one specific problem. But are you sure that the other 99 usages of that method call work fine with that change?!

Final caveat: Java 9 introduced the module concept, so you are now finally able to have something public, but still not usable from outside your module. But that is more of a theoretical addendum, I would still go with the base rule and make not things public unless I have good reasons to do so. If you want to access that information, say for unit tests, then a package protected getter should do.

like image 169
GhostCat Avatar answered Sep 29 '22 19:09

GhostCat


There is no practical difference between having a final field declared public or having it private with a public getter.

There are a lot of theoretical handwavy arguments why it's really bad to have public fields, but there actually is no real practical reason not to do it. Yes, in theory you could change the getter later to do something different, but you probably won't. Even if you want to most people will tell you a getter should really just return the field it gets without additional logic.

Just to be more clear, both options are equally wrong. Fields shouldn't be public, and there shouldn't be a getter either. But, if you do one of those, the other is equally wrong. Hope that helps :)

like image 32
Robert Bräutigam Avatar answered Sep 29 '22 19:09

Robert Bräutigam