This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 3 years ago.
Looking and digging through my code, I noticed that we usually use the #Setter from Lombok thoroughly.
It made me wonder about the usage of #Setter.
Indeed, is it more interesting to use #Setter than simply making the field accessible through its visibility?
From what I understand, setters are preferable in one of those cases (thanks to Why use getters and setters/accessors?):
you want your object to react to a field being set
you want to lazily compute the value of a field
you make want to mock (although I deeply think testability should not lead your code design)
class may be inherited and setters overridden
But there are some object which does not match any of those cases.
In code terms, is this:
#Getter
#Setter
public class Person{
private String firstName;
private String lastName;
}
more preferable (in terms of maintainability and readability) than this:
public class Person{
public String firstName;
public String lastName;
}
As a side note, I would like to add that I find person.firstName = "Vincent" more readable than person.setFirstName("Vincent").
You are completely mixing encapsulation with visibility.
Firstly, it's not about lombok. Lombok avoid bolier plate code, in this case, having a setter method. Java beans or DTOs have getter and setter method usually by convention and lombok does it at generated class rather than the java file.
Related
This question already has answers here:
Lombok #Builder inheritance workaround
(3 answers)
Closed 4 years ago.
I have a class that stores many fields (both primitive types and objects like String or List). All fields are required and need to be set only once, when the object is created.
What is the correct way to instantiate this using Lombok while ensuring these conditions are met:
1) No warnings due to risk of mutable objects being returned by Setters.
2) Do not use a constructor to instantiate all fields, since number of fields can be >10.
3) Be able to inherit and extend this class, where each subclass will only add more fields, and do nothing else.
4) Be serialization friendly (i.e., have an empty public constructor).
class ParentData {
int id;
String name;
}
class ChildData extends ParentData {
long childId;
long[] friendId;
String[] friendNames;
}
Currently, even if I set the fields as private final, I get findBugs errors that the [] objects are mutable.
May be you could take a look on Builder in lombok
If Constraint 3 means that you want to restrict what subclasses are allowed to do (i.e., be sure that they will never be mutable), then that is not satisfiable, because you cannot enforce immutability on subclasses in Java. If it means "it should be possible to add fields", everything is fine.
That said, you should go with #SuperBuilder and #Getter on the classes. Instead of arrays, use collections with #Singular; Lombok's SuperBuilder will use immutable collection classes then.
Use #NonNull on required fields.
Add a #NoArgsConstructor for subclasses and serialization frameworks.
I think that's the best you can get with Lombok. There may still be warnings from your linter, but at least partially because the generated code is too complex for it.
PS: Use the current Lombok edge version 1.18.3 or wait for release 1.18.4 for #NonNull support in #SuperBuilder.
This question already has answers here:
When is using public fields acceptable?
(3 answers)
Closed 5 years ago.
Java has different access levels for fields:
public
protected
default
private
Due to encapsulation concept we always trying to use private modifier with getters and setters of needed access level. It has various advantages shown in this answer. Since getters and setters are so cool, when should we prefer public/protected/default Object field; to private Object field; with public/protected/default getters and setters?
Clarification: I perfectly understand why and what are getters, setters and access modifiers. I just want comprehensive answer for a certain question above.
We can achieve complete encapsulation in java by making members of a class private and access them outside the class only through getters and setters. Although a lesser degree of encapsulation can be achieved by making the members public or protected.
I'm using lombok's annotation #Data when writing pojos because it automatically generates constructor, hashCode as well as other methods for me. It worked like a charm until I was trying to use #Data in such a pojo class.
#Data
public class MyPojo {
private final String name;
private final int from;
private final int to;
// other fields
}
What I need to do is to restrict values of from and to when creating this pojo so that to will always be greater than from, but it seems that in order to achieve this logic, I have to rewrite the constructor all by myself with lots of code similar to this.name = name.
PS: I think using super from inheritance could be a workaround, but it may make the program harder to be understood.
Is there any better way to satisfy this need?
#Data annotation is not providing any way to validate construction arguments. I feel you need to annotate your pojo with #Getter #Setter #ToString #EqualsAndHashCode annotations and write constructor on your own.
Looking at Lombok's website, I don't see any way to restrict constructor parameters to specific values, especially relative to another variable that may have not been initialized yet. You'll probably have to create a concrete constructor for this class.
but it may make the program harder to be understood
I really wouldn't worry about that as you're already using Lombok, which would make any big program very confusing when trying to track down a specific field/method.
public #Data class Person { ... }
As I know, when I mark a class with the #Data annotation, Lombok will provide getters for all fields, setters for all non-final fields. I want to turn off getter and setter only for one instance non-final field, how can I reach that?
What did I expect? To find an annotation like
#Setter(provide=false)
#Getter(provide=false)
private Map<...> dialogs;
or
#Data(excludeFields={"dialogs"})
I googled a lot and looked for on the official site, but I've found nothing.
Your help will be appreciated. Thank you.
You can use #Getter(AccessLevel.NONE) #Setter(AccessLevel.NONE) on the field as described on the website.
Disclosure: I am a Lombok developer.
In order to avoid generating Getter/Setter for a specific field, you can use AccessLevel.NONE, as described in webpage for Getter/Setter
#Data
public class Person {
private String name;
private int age;
#Getter(AccessLevel.NONE) #Setter(AccessLevel.NONE)
private Map<String, String> dialog;
}
EDIT: This answer originally proposed to use AccessLevel.PRIVATE. The correct approach is to use AccessLevel.NONE as #Roel_Spilker mentioned in the other answer. But this answer was accepted by the questioner. In order to avoid future confusion, I edited this to use correct approach.
This question already has answers here:
Why use getters and setters/accessors?
(37 answers)
Closed 8 years ago.
I had been asked the following question in an interview and i am curious to know the answer.
There are two classes as following,
public class EmployeeA{
public int empId;
}
public class EmployeeB{
private int empId;
public void setEmpId(int empId){this.empId = empId;}
public int getEmpId(){return empId;}
}
There are two classes where one class has a public instance field and other have a private field with getters and setters. In this case, which is better implementation and why?
[I have learned that making instance variable private is the better idea. But in both cases i can modify the value of empId attribute. ]
The one-word answer they're probably looking for is "encapsulation".
By encapsulating the private field value, you have the opportunity to change the logic on how the value is set/retrieved in the future. Say, for example, you want to validate on set and filter on retrieval (get). By encapsulating the value, your creating an API which allows for better maintenance moving forward.
Maybe a bit off-topic, although people usually talk about "encapsulation" when talking about "getter/setter", "getter/setters" are actually still far from proper encapsulation.
This famous "why getter and setter methods are evil" is something worth to read. When we say getters and setters are evil, it doesn't mean that we should expose variable directly. It is about further hiding internal data by providing meaningful behavior in class, instead of providing accessors for properties. Although there are a lot of cases we still need accessors, this is something that worth giving attention when you are designing.
Going back to your question, if it is me, I will answer: providing getters and setters provides a minimal level of encapsulation and allow us to do extra work or derives data when we are setting and getting properties. However, for a proper encapsulation, I would rather design the Employee class to provide proper behaviors, instead of simply acting as a value object which only provides bunch of getters/setters.
The accesssor (getter) and mutator (setter) are JavaBean requirement but not all classes in Java must follow this design pattern. Why not creating this class as immutable by having a constructor that take the id (or even better, a static factory). You can then provide an accessor for the the id. That is generally not a good idea to be able to change the id of an object, if the id is used in a Map as the key and you change it, good luck to retrieve you object... Make the class immutable solve this kind of problem.