Consider the below DTO. In SonarQube scan it says the fields name and age are duplicated in getters and setters. Why is this even an issue? Can someone tell me how to fix this, as I have a ton of DTOs with the same issue?
public class Employee {
String name;
int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age= age;
}
public int getAge() {
return age;
}
}
The point is, if you have multiple DTOs that all have the same "name" and "age" property, it would make sense to define a "Person" class with those properties and have Employee extend from that.
In any case, SonarQube issues are just issues. It certainly does not say "it must be removed". You are free to interpret the severity of the problem in your own context. There is no doubt that duplicated code and properties can be a maintenance problem. If you choose to ignore it, that's up to you.
Related
Suppose I have a superclass A and it has fields
class A {
String name;
int age;
setName(String name);
getName();
setAge(int age);
getAge()
}
I have multiple classes that extend A and add more fields along with the getters and setters.
Now there is another class, say B, which requires name and age, which is already provided by class A.
So should I go ahead and create class B without any field and simply it extends class A, or should I directly use class A?
class B extends A {}
P.S - I am using generics, which gives me a warning when I directly use superclass A, but the functionality is working fine. Please suggest.
Mostly the design wont be proper and justified if u just create a Class that do not have its own state, but yes it make sense if
A is abstract class i.e. you want to restrict the users to create an instance of A hence mark it abstract , then by creating B you are creating an implementation of A.
below is the example for the same
abstract class A{
protected String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class B extends A{}
also to make code more dynamic at runtime if u want to just use the parent class fields into ur function then probably u can do this
abstract class A{ // you can altogether remove 'abstract' and not create a B class
protected String name;
protected int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class B extends A{}
class C extends A{
protected String location;
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
}
now see the below method
public static <T extends A> void printName(List<T> list) {
for (T t : list) {
System.out.println(t.getName());
}
}
this qualifies for List<B>, List<C>
There is really no reason, that I can think of, where you need to extend a class without changing anything. Maybe you feel that you will need it in the future. This violates the YAGNI principal.
Just use Class A. You can make changes when they are needed.
It really is pointless. If it gives you a warning, there is probably a good reason for it. Unless you have a niche use case and know what you are doing, the empty class serves no purpose other than adding useless files to your project
I need your recommendations. which way is the best in terms of software engineering (Readability, Usability )
I have object person
public class Person {
private String name;
private String surname;
public Person(String name, String surname) {
super();
this.name = name;
this.surname = surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
}
I have method savePerson.
First way is to set request parameters to variable before initialise object.
public void handle(Map<String, Object> map, HttpServletRequest request) throws Exception {
String name = request.getParameter("name");
String surname = request.getParameter("surname");
Person person = new Person(name, surname);
personService.savePerson(person);
}
Second way is to set request parameters set them as constructors parameters.
public void handle(Map<String, Object> map, HttpServletRequest request) throws Exception {
Person person = new Person(request.getParameter("name"), request.getParameter("surname"));
personService.savePerson(person);
}
You have to consider that the compiler transforms your operations in a sort of binary version that is a little optimized.
Your second version is less readable but it has only one code line.
The compiler will do it for you, so you can choose your version according to your writing style.
If you have to share your code with other persons, the first method will probably be the best because it is more simple, and in a scenario where the execution efficiency is the same, it can become your discriminant.
The first way is more readable and easy to debug, than the second one. Moreover, if you add other fields in your Person object the second way will be totally messy.
In order to simply even more the code you can use Lombok to avoid writting Getter and Setter for your Person class
First one for sure. It is readable and the instructions are clearly visible. It being basic can be understood by any junior level developer as well so if someone else works on this code, it will be easy for him/her to make the necessary changes.
Always the code that is readable must be used so as to keep the things structured and more manageable.
basically I created a Person class and a constructor which sets the name,last name,age of the Person.all the properties of the class were set the private as it should be. I have made setters and getters for all the properties. On the main method I tried to override one of the setters just for practice reason. Its did draw an error saying Person.name not visible which means it cannot access private, Why this is happening, I mean if wasn't overriding the method it would have access. but if I set it to protected mode i will work.
Here is the code:
class Person {
private int age;
private String name;
private String last_name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public Person(int age, String name, String last_name) {
this.age = age;
this.name = name;
this.last_name = last_name;
}
}
public class main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person per = new Person(15,"bb","Sb") {
public void setName(String name) {
this.name = "aaaa";
}
};
per.setName("asdfaf");
System.out.println(per.getName());
}
}
A private member is only accessible in the class in which it is declared.
You created an anonymous sub-class of Person and tried to access a private member of the super-class from the sub-class. This is never allowed.
When developers of a class wish to allow access to certain members of the class to its sub-classes, they set the acess level to protected.
You have created a class named Person and in the following lines you are trying to create an anonymous subclass:
Person per = new Person(15,"bb","Sb") {
public void setName(String name) {
this.name = "aaaa";
}
};
As mentioned in doc:
A subclass does not inherit the private members of its parent class
Here your anonymous subclass is trying to access private field name directly and so is the error. You can use getter/setter which are public. You can also check this related question on SO.
You cannot access private fields from outside your class, even if you are overriding it. You are basically defining a new subclass of Person in your main(), which isn't allowed access to the private field Person.name. However, it can access a protected field.
Basic idea behind overriding is to redefine existing functionality and give new definition to it. If you refer to documentation, private member variables are only accessible in it own class. That why it is not available in your anonymous sub-class implementation.
Note: Generally we do not override setter methods as they are not a functionality.
This is called encapsulation . You can not access private vars from other classes . you can find more description here
Both methods work, however which is the proper way to do it?
Method one:
public class Object {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object(String name){
this.name = name;
}
}
Method two:
public class Object {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//Changed this.name = name to setName(name)
public Object(String name){
setName(name);
}
}
I've searched around but couldn't find an exact question that referred to this. If there is one, free to post the link and I'll remove the question
My first thought was to use the setter in the constructor. So if you want to change how the name is stored, or if you want to add any other behavior while setting the name, you just have to change it once.
But thinking just a bit more on this, I think using direct access to the variable is better if the class is not final and the method is not private. Otherwise someone could extend your, override the method, causing your constructor to call their method with unpredictable behavior.
Rule of thumb: If the class is not final, you should only call private methods in the constructor.
While using a setter in the constructor reduces code duplication, calling overrideable methods (ie non final / non private methods) in a constructor is discouraged - it can lead to weird bugs when extending a class.
Consider the following case (based off of your example):
public class Object {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//Changed this.name = name to setName(name)
public Object(String name){
setName(name);
}
}
With the following subclass:
public class SubObject extends Object {
private String Id;
#Override
public void setName(String name) {
super.setName(name + Id);
}
public SubObject(String name){
super(name);
this.id = "1";
}
}
Creating an instance of SubObject will cause a null pointer, as setName() is called in the constructor, but the implementation of setName() relies on the Id field having been initialized.
Someone extending a class should not have to go check the source code of the super class to ensure the constructor isn't calling overrideable methods.
If all the setter and constructor do is a simple assignment, it doesn't matter which of the two ways you choose.
However, if you need to perform some validations before assigning the new value to the member, it makes sense to have that logic in a single place, which means calling the setter method from the constructor is the better option.
I would NOT use the setter in the constructor. This because if someone added any other behavior while setting the name in the setter, I'd consider it a collateral effect.
If setName() coontains some inner logic about how the name should be set, then I would choose 2. On the other hand, if setName() contains some aditional code that needs to be run when name is set, i would choose 1.
Let me make a bit more complex situation so I can express my point:
class Person {
private String firstName;
private String lastName;
private boolean wasRenamed;
//getters...
public Person(String fullName) {
???
}
public void setFullName(String fullName) {
???
}
}
Here we have Persons with first and last names, also we want to keep record who was renamed and who not. Let's say fullName contains first and last name separated by space. Now let's look at 2 different approaches you provided in your question:
Not call setFullName() in costructor: This will lead to code duplicity (spliting fullName by space and assigning it to first and last name.
Do call setFullName() in costructor: This will add extra trouble with the wasRenamed flag, since setFullName() has to set this flag. (This could be solved by simply resetting the flag back to false in constructor after calling setFullName(), but let's say we don't want to do that)
So I would go with a combination of 1 and 2, and split the inner logic of setting the name and the additional code that needs to run before/after name is set into different methods:
class Person {
private String firstName;
private String lastName;
private boolean wasRenamed;
//getters...
private void setFullName0(String fullName) {
//split by space and set fields, don't touch wasRenamed flag
}
public Person(String fullName) {
setFullName0(fullName);
}
public void setFullName(String fullName) {
setFullName0(fullName);
wasRenamed = true;
}
}
How can I tell (if ever) Eclipse to make a single line for a getter or setter when using auto formatting?
public User getUser() {
return user;
}
to:
public User getUser() { return user; }
If you don't like all the boilerplate which Java forces you to write, you might be interested in Project Lombok as an alternative solution.
Instead of trying to format your code to minimize the visual impact of getters and setters, Project Lombok allows them to be added by the compiler behind the scenes, guided by annotations on your class's fields.
Instead of writing a class like this:
public class GetterSetterExample {
private int age = 10;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
protected void setName(String name) {
this.name = name;
}
}
You would write:
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
public class GetterSetterExample {
#Getter #Setter private int age = 10;
#Setter(AccessLevel.PROTECTED) private String name;
}
(example from: http://projectlombok.org/features/GetterSetter.html)
Java code formatting in Eclipse does not differentiate between getters/setters and any other methods in a class. So this cannot be done by built-in eclipse formatting.
As other posters have stated, Eclipse cannot currently do this. There is a feature request at https://bugs.eclipse.org/bugs/show_bug.cgi?id=205973 however, and if it gets enough upvotes there's a chance somebody might implement it...
How about using formatter on/off tags:
//#formatter:off
#override public final String getName() {return this.name;}
//#formatter:on
You will need to make sure that the on/off tags are enabled (preferences/java/code style/formatter/edit/on off tags). This may be the default.
For just one method it will be just as ugly as a three line getter method, but if you have more than four or five then it will look neater.
It also allows you to group the getters and setters for a property together rather than all the getters and then all the setters.
That is my solution, anyway.