Related
I need a small Container-Class for storing some Strings which should be immutable. As String itself is an immutable type, I thought of something like that:
public final class Immu
{
public final String foo;
public final String bar;
public Immu(final String foo, final String bar)
{
this.foo = foo;
this.bar = bar;
}
}
Many people seem to object using public fields at all and use Getters instead. IMHO this would be just boilerplate in this case, because String itself is immutable.
Other thoughts I may be missing on this one?
I would do what you believe is simplest and clearest. If you have a data value class which is only used by a restricted number of classes. esp a package local class. then I would avoid getter/setters and use package local or public fields.
If you have a class which you expect other modules/developers to use, following a getter/setter model may be a safer approach in the long run.
The problem is the uniform access principle. You may later need to modify foo so that it's obtained through a method instead of being fixed, and if you exposed the field instead of a getter, you'll need to break your API.
This answer is obviated:
Why not
interface Immu { String getA() ; String getB ( ) }
Immu immu ( final String a , final String b )
{
/* validation of a and b */
return new Immu ( )
{
public String getA ( ) { return a ; }
public String getB ( ) { return b ; }
}
}
I found this thread hoping for some actual arguments, but the answers I've seen here didn't help me all that much. After some more research and thinking I think the following has to be considered:
public final looks cleanest for immutable types.
Mutable types could be altered by accessors even if this is not intended - in concurrent environments this could lead to a lot of headaches.
There can be no no-arguments constructor. This is importent if you need factory methods (e.g. for LMAX Disruptor). In a similar way instantiating your objects via reflection becomes more complicated.
Getters and setters can have side effects. Using public final clearly tells the programmer that no hidden magic is occuring and the object is inherently dumb :)
You can't return a wrapper or a derived class instance to the accessor. Then again, this is something you should know about when the field is assigned its value. In my opinion container classes should not be concerned about what to return to whom.
If you're mid development and no guideline is stopping you and the project is isolated or you have control over all involved projects I'd suggest using public final for immutable types. If you decide you need getters later on, Eclipse offers Refactor -> Encapsulate Field... which automatically creates these and adjusts all references to the field.
I use the public-final-field (anti?)pattern on home projects for classes which are basically an immutable data structure with a constructor, along with absolute basics like equals(), hashCode(), toString(), etc. if required. (I'm avoiding the word "struct" because of the various different language interpretations of it.)
I wouldn't bring this approach to someone else's codebase (work, public project, etc) because it would likely be inconsistent with other code, and principles like When In Rome or Least Surprise take priority.
That said, with regard to Daniel C. Sobral's and aioobe's answers, my attitude is that if the class design becomes a problem because of unforeseen developments, it's the work of 30 seconds in an IDE to privatise the fields and add accessors, and no more than 5 or 10 minutes to fix broken references unless there are hundreds of them. Anything that fails as a result gets the unit test it should have had in the first place.:-)
[Edit: Effective Java is quite firmly against the idea, while noting that it's "less harmful" on immutable fields.]
Forget about encapsulation, immutability, optimization and all other big words. If you are trying to write good java code, I would recommend you just use getter simply because it is java friendly, and most importantly it saves ton of time googling why.
For example, you probably would not expect using streams when you write the code, but later you found
listOfImmus.stream().map(immu -> imm.foo).collect(Collectors.toSet()); // with field
listOfImmus.stream().map(Immu::getFoo).collect(Collectors.toSet()); // with getter
Supplier<String> s = () -> immu.foo; // with field
Supplier<String> s = immu::foo; // with getter
// final fields are hard to mock if not impossible.
Mockito.when(immuMock.getFoo()).thenReturn("what ever");
//one day, your code is used in a java Beans which requires setter getter..
¯\_(ツ)_/¯
This list can be long or short or may be none of them makes any sense to your use case. But you have to spend time convincing yourself (or your code reviewers) why you can or should rebel against java orthodoxy.
It is better to just write the getter/setter and spent the time for something more useful: like complaining java
Since Java 16, you can use records.
public record Immu(String foo, String bar) {}
All of a record's attributes are automatically final and it automatically has methods like equals(…) and toString() and the constructor.
The getters of the attributes have the same name as the attributes, in this case, they are foo() and bar().
The methods can be overridden, more information is in the documentation.
It is not very clear if someone is going to use your code through an API.
You are also missing an opportunity to validate the input, if you are going to require some later.
Using public final may be fine for such small job, but it cannot be adapted as a standard practice,
Consider the situation below.
Public class Portfolio {
public final String[] stocks;
}
Of course, being immutable, this object is initialized vis constructor, and then accessed directly. Do I have to tell you the problem in it? It’s evident!
Consider your client writing the code like below -
Portfolio portfolio = PortfolioManager.get(“Anand”);
Portfolio.stocks[0] = “FB”;
portfolio.calculate();
Is this doable? Your client libraries are able to manipulate the state of your objects, or rather able to hack within your runtime representation. This is a huge security risk, and of course tools like SONAR catch it upfront. But its manageable only if you are using getter-setters.
If you are using getters, you can very well write
Public class Portfolio {
private final String[] stocks;
public String[] getStocks() {
return Arrays.coptOf(this.stocks);
}
}
This prevents you from potential security threat.
Looking at the above example, using public final is strongly discouraged if you are using arrays. In such case, it cannot become a standard. A person like me, will refrain from using a code practice that cannot become a uniform standard across all data types. What about you?
So my goal is to return some objects as the response body from a Spring REST controller. The thing is, these two objects point each other, something kind of like this:
public class Person {
private Set<Team> teams;
}
public class Team {
private Set<Person> members;
}
If I return these two objects from a controllers mapping method right away, the generated response will be infinite and will probably crash the browser, because the members set has people, and each person has a set of teams, and so on, and everything gets returned infinitely.
How can I manage, instead of showing the whole list of, say, members, to display just the name of each of the members?
Any help will be much appreciated, thanks!
If you are using jackson then you must use jackson provided solution to problem you are mentioning.
#JsonManagedReference
#JsonBackReference
Also look at this link which might be helpful :
Infinite Recursion with Jackson JSON and Hibernate JPA issue,
Also
https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations#object-references-identity
Which of the following is better? Is it even opinion-based or are there any relevant differences? Can one or the other be favored in some scenarios?
public class MyClass {
private Integer myField;
public void setMyField(Integer myField) {
this.myField = myField;
}
public Integer getMyField() {
return myField;
}
}
I need a method to check wether something is allowed or not. Please, let's not talk about the sense of this code example. It's just a minimal example.
Implementation 1
public boolean isAllowed() {
MyEnum.ALLOWED.getInt().equals(getMyField());
}
Implementation 2
public boolean isAllowed() {
MyEnum.ALLOWED.getInt().equals(myField);
}
Edit:
This post does not have an answer in the linked question (see comments to the initial post)
Which of the following is better? Is it even opinion-based or are
there any relevant differences? Can one or the other be favored in
some scenarios?
It is question of good practice I think. The difference is in the readability of the code.
As a general rule, you should avoid indirection if not required.
The current instance of MyClass has the information in one of these fields to implement the operation. It doesn't need to hide its internal state to itself. So in internal, MyClass has no valuable reason to favor the use of the getMyField() over the direct use of the myField field.
The getMyField() accessor is more suitable to be used by clients of the class.
So I think that it is better in any case in your example code :
public boolean isAllowed() {
MyEnum.ALLOWED.getInt().equals(myField);
}
Edit :
Beyond the readability, here is an example why you have no interest to couple the internal state to a public getter.
Suppose during the development phase you remove from the class the public getMyField() method because not need or not needed any longer for clients of the class, if isAllowed() relies on getMyField() in its implementation, it will be broken and you should replace it by myField.
My answer won't be the most informative however it will come from direct experience of dealing with this pattern. When designing an object it is often tempting to directly access member fields rather than rely on accessors. The desire stems from wanting to simplify the object and avoid adding clutter from methods that simple return a value. Taking your example a step further to add context & meaning:
public class MyClassmate {
private Integer age;
public MyClassmate(Integer age) {
this.age = age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getAge() {
return age;
}
}
Here age is a simple number and it appears unnecessary to add getters/setters around it. If we add the following method you would be tempted to directly access the field since there is no change in behavior:
public Integer calculateScore() {
if(age > 21) return 100 - getNumberOfIncorrectAnswers();
//Add 10% before for younger students
else return (100 - getNumberOfIncorrectAnswers()) + 10;
}
Your object may then grow new features with methods relying on the age field where you continue to use it directly. Later, you might alter the way age is originated and pull the value from across a network. You might not want to incorporate the networking logic in the constructor because it is an expensive operation which should only be triggered as needed. The calculateScore() method could make the network connection and discover the age but then too would all of the other methods that rely on age. But what if calculateScore looked as follows?:
public Integer calculateScore() {
if(getAge() > 21) return 100 - getNumberOfIncorrectAnswers();
//Add 10% before for younger students
else return (100 - getNumberOfIncorrectAnswers()) + 10;
}
You could then enhance the object changing the way it derives age without touching the calculateScore() method. This means your method follows Open Closed Principle (OCP). It is open for enhancement but closed to change, or you didn't have to change the method source in order to change where it gets the age.
Depending on the complexity of your app and object model there may still be times when encapsulated access is overkill but even in these scenarios it is good to understand the tradeoffs of direct field access and these more simplistic scenarios are mostly rare.
In general you should understand that the need for encapsulation is almost never immediate. It appears over time as the object grows and if the object is not setup with encapsulation from its onset it is more expensive to phase it in. That's what makes this approach so difficult to appreciate. It takes experience (i.e. making the typical oversimplification and suffering several times over several years) to feel why encapsulation is necessary. It is not something you can eyeball and detect.
That said, this used to be a much bigger problem than it is today when IDEs were not as full featured. Today you can use the built in encapsulate fields refactoring in certain IDEs like IntelliJ to introduce the pattern as you need it. Even with modern IDEs it is still favorable to practice encapsulation from the onset.
I would recommend using the getter because in certain scenarios, it can have some additional logic (like formatting, checking for nulls and so on). So you may be losing some logic when using the field itself.
To keep a good encapsulation, the first think you need to think is which methods are you going to expose outside your class, if here, for example you are going to use only the is allowed method, I would make public only that method, and define the field in the constructor, if the field is suitable to change then you will need getter/setters but always depends on what do you want to offer from your class. And keep as much encapsulated as you can.
public class MyClass {
private Integer myField;
MyClass(Integer myField){
this.myField = myField;
}
//Only this method is offered nobody need to know you use myField to say true/false
public boolean isAllowed() {
MyEnum.ALLOWED.equals(myField);
}
}
In my Software Engineering courses I was told to realize the "principle of secret". Thus, you should always use getter- and setter-routines. This way you can be sure that nobody accesses the member variable by accident.
Strange functions or objects may never see or even change member variables except you explicitly tell them to do so by setter and getters.
Due to your attribute being private, you can only securely access it within other class using getter or setter methods. So I would say that the best implementation is the one following the encapsulating principle, i.e., the one using the getter instead of accessing directly.
This will prevent data leaks as well.
https://www.tutorialspoint.com/java/java_encapsulation.htm
I need a small Container-Class for storing some Strings which should be immutable. As String itself is an immutable type, I thought of something like that:
public final class Immu
{
public final String foo;
public final String bar;
public Immu(final String foo, final String bar)
{
this.foo = foo;
this.bar = bar;
}
}
Many people seem to object using public fields at all and use Getters instead. IMHO this would be just boilerplate in this case, because String itself is immutable.
Other thoughts I may be missing on this one?
I would do what you believe is simplest and clearest. If you have a data value class which is only used by a restricted number of classes. esp a package local class. then I would avoid getter/setters and use package local or public fields.
If you have a class which you expect other modules/developers to use, following a getter/setter model may be a safer approach in the long run.
The problem is the uniform access principle. You may later need to modify foo so that it's obtained through a method instead of being fixed, and if you exposed the field instead of a getter, you'll need to break your API.
This answer is obviated:
Why not
interface Immu { String getA() ; String getB ( ) }
Immu immu ( final String a , final String b )
{
/* validation of a and b */
return new Immu ( )
{
public String getA ( ) { return a ; }
public String getB ( ) { return b ; }
}
}
I found this thread hoping for some actual arguments, but the answers I've seen here didn't help me all that much. After some more research and thinking I think the following has to be considered:
public final looks cleanest for immutable types.
Mutable types could be altered by accessors even if this is not intended - in concurrent environments this could lead to a lot of headaches.
There can be no no-arguments constructor. This is importent if you need factory methods (e.g. for LMAX Disruptor). In a similar way instantiating your objects via reflection becomes more complicated.
Getters and setters can have side effects. Using public final clearly tells the programmer that no hidden magic is occuring and the object is inherently dumb :)
You can't return a wrapper or a derived class instance to the accessor. Then again, this is something you should know about when the field is assigned its value. In my opinion container classes should not be concerned about what to return to whom.
If you're mid development and no guideline is stopping you and the project is isolated or you have control over all involved projects I'd suggest using public final for immutable types. If you decide you need getters later on, Eclipse offers Refactor -> Encapsulate Field... which automatically creates these and adjusts all references to the field.
I use the public-final-field (anti?)pattern on home projects for classes which are basically an immutable data structure with a constructor, along with absolute basics like equals(), hashCode(), toString(), etc. if required. (I'm avoiding the word "struct" because of the various different language interpretations of it.)
I wouldn't bring this approach to someone else's codebase (work, public project, etc) because it would likely be inconsistent with other code, and principles like When In Rome or Least Surprise take priority.
That said, with regard to Daniel C. Sobral's and aioobe's answers, my attitude is that if the class design becomes a problem because of unforeseen developments, it's the work of 30 seconds in an IDE to privatise the fields and add accessors, and no more than 5 or 10 minutes to fix broken references unless there are hundreds of them. Anything that fails as a result gets the unit test it should have had in the first place.:-)
[Edit: Effective Java is quite firmly against the idea, while noting that it's "less harmful" on immutable fields.]
Forget about encapsulation, immutability, optimization and all other big words. If you are trying to write good java code, I would recommend you just use getter simply because it is java friendly, and most importantly it saves ton of time googling why.
For example, you probably would not expect using streams when you write the code, but later you found
listOfImmus.stream().map(immu -> imm.foo).collect(Collectors.toSet()); // with field
listOfImmus.stream().map(Immu::getFoo).collect(Collectors.toSet()); // with getter
Supplier<String> s = () -> immu.foo; // with field
Supplier<String> s = immu::foo; // with getter
// final fields are hard to mock if not impossible.
Mockito.when(immuMock.getFoo()).thenReturn("what ever");
//one day, your code is used in a java Beans which requires setter getter..
¯\_(ツ)_/¯
This list can be long or short or may be none of them makes any sense to your use case. But you have to spend time convincing yourself (or your code reviewers) why you can or should rebel against java orthodoxy.
It is better to just write the getter/setter and spent the time for something more useful: like complaining java
Since Java 16, you can use records.
public record Immu(String foo, String bar) {}
All of a record's attributes are automatically final and it automatically has methods like equals(…) and toString() and the constructor.
The getters of the attributes have the same name as the attributes, in this case, they are foo() and bar().
The methods can be overridden, more information is in the documentation.
It is not very clear if someone is going to use your code through an API.
You are also missing an opportunity to validate the input, if you are going to require some later.
Using public final may be fine for such small job, but it cannot be adapted as a standard practice,
Consider the situation below.
Public class Portfolio {
public final String[] stocks;
}
Of course, being immutable, this object is initialized vis constructor, and then accessed directly. Do I have to tell you the problem in it? It’s evident!
Consider your client writing the code like below -
Portfolio portfolio = PortfolioManager.get(“Anand”);
Portfolio.stocks[0] = “FB”;
portfolio.calculate();
Is this doable? Your client libraries are able to manipulate the state of your objects, or rather able to hack within your runtime representation. This is a huge security risk, and of course tools like SONAR catch it upfront. But its manageable only if you are using getter-setters.
If you are using getters, you can very well write
Public class Portfolio {
private final String[] stocks;
public String[] getStocks() {
return Arrays.coptOf(this.stocks);
}
}
This prevents you from potential security threat.
Looking at the above example, using public final is strongly discouraged if you are using arrays. In such case, it cannot become a standard. A person like me, will refrain from using a code practice that cannot become a uniform standard across all data types. What about you?
I'm now working with code that looks like this
public String getName(User user) {
user.setSth(...);
return user.getName();
}
I think it's bad practice to change objects passed as parameters. Is there a tool that detects that kind of code? I looked at findbugs, pmd and checkstyle, but could not find any check for this.
P.S. sorry for bad example.
I think you are already on the right track: your best tool to detect this sort of code is almost certainly Findbugs. However, you will probably need to write your own detector for this pattern. Here is an example of how you would write a detector, though it isn't exactly the detector that you're looking for.
Caveat: I don't really agree that a side-effecting getter is always bad style. However, if you really want to find that sort of thing, I would recommend Findbugs.
You won't find anything because, from a tool's point of view, "getName" and "setSth" are just method calls. Humans say "this is a getter" and "this is a setter" but tools don't. In fact, getName() is not a getter because getters don't accept arguments.
So the tool can't see anything unusual because methods change objects all the time.
If you want to enforce this rule, have a look at extending findbugs and PMD. Both allow you to define additional constraints. What you're looking for is probably:
If method name starts with "get"
AND method body calls method of any object passes as parameter
then print a warning. That shouldn't take too long. Run this and you will see how many "false positives" you get (warnings about methods which are actually OK). This will help you determine whether it's worth to pursue this further. Plus you'll have a new item to add to your CV :)
You could make User immutable (declare it final, declare all properties final and remote the setters. I know that isn't practible everywhere but in many places that is good and you will have no problems in passing that to other functions).
If you have to "change" something, you can implement functions like newId in that sample:
public final class User {
private final String name;
private final int id;
User(String name, int id) {
this.name = name;
this.id = id;
}
public User newId(int newId) {
return new User(this.name, newId);
}
//getters here;
}
The built in String, Integer, ... classes do that, too.
You can create an interface called UserView containing only "getters", make User implement it and use the new UserView interface as the type of parameter.
interface UserView{
public String getName();
...
class User implements UserView...
public String getName(UserView user) {
user.setSth(...); // Will not compile
return user.getName();
}
Actually this is something that in C++ was very easy to do via the const qualifier. You would define a parameter as const and for that parameter you could only call methods defined as const - usually, getters.
In Java this is absent and frankly, I don't really mind. As mentioned there are source code analyzers which can check this behavior, as well as meta-programming methods to do this as well.
Personally, I believe that if the method is named properly, there is no problem of passing an object to it so that is it modified.
There are tools that can "reason" about code on a higher level than compilers typically do. Declarative Metaprogramming for example is a discipline that allows writing programs to check if another program conforms to a certain design, or, conversely, to mine for code smells and anti-patterns.
Some links:
http://prog.vub.ac.be/DMP/
http://www.cs.bris.ac.uk/Publications/pub_master.jsp?id=1000273
and for the rest
http://www.google.com/search?num=100&hl=en&q=Declarative+Metaprogramming
You're looking for something like "const" in C++ that will enforce making the parameter value as immutable as the reference that's passed in. Immutable objects guarantee that, if you can live with them.
You're arguing that this is "bad" because side effects like this can surprise a user. That's valid, but it's only harmful if it's an unwanted surprise.