JAVA tool class – generate getter and setter methods of beans (entity classes) and annotations of classes and methods

Function description

This is a tool method that does the following.

(1) Quickly generate getter and setter methods of entity classes;

(2) Add comments to the class. Hovering the mouse on the class name after new can prompt the description of the corresponding class in the code assistant;

(3) Add comments to the getter and setter methods, and the code assistant will prompt instructions for the corresponding methods when calling;

(4) The generated setter method will return the object of the current class to meet the calling form of chain set.

Tool code

Without further ado, let’s go straight to the code:

package com.po;

import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class _produceGS {
public static void main(String[] args) {
FileWriter fw = null;
String path = "src/com/po/Student.java";
try {
List<String> sL = Files.readAllLines(Paths.get(path));
Map<String, List<Map<String, String>>> m = new HashMap<>();
int lv = 0; List<String> classNameL = new ArrayList<>();
boolean func = false;
for(String s : sL) { // The first loop finds all attributes under all classes
if(s.indexOf("class ") > -1 & amp; & amp; s.indexOf("{") > s.indexOf("class ")) { // It is a class
classNameL.add(s.substring(s.indexOf("class ") + 6, s.indexOf("{")).trim());lv + + ;} // Get the class name
if(s.indexOf(";") > 0 & amp; & amp; s.indexOf("package ") < 0 & amp; & amp; s.indexOf("import ") < 0 & amp; & amp; s.indexOf("this.") < 0 & amp; & amp; s.indexOf("return ") < 0) { // is a property
String strTemp = "";
List<Map<String, String>> l = m.get(classNameL.get(lv - 1));
if(l == null) {l = new ArrayList<>();}
Map<String, String> propM = new HashMap<>();
if(s.indexOf("=") > 0 & amp; & amp; s.indexOf("=") < s.indexOf(";")) {
strTemp = s.substring(0, s.indexOf("=")).trim();
propM.put("value", s.substring(s.indexOf("=") + 1, s.indexOf(";")).trim()); // Attribute value
}else{strTemp = s.substring(0, s.indexOf(";")).trim();} // Everything up to the end of the attribute name
propM.put("name", strTemp.substring(strTemp.lastIndexOf(" ") + 1)); // Property name
strTemp = strTemp.substring(0, strTemp.lastIndexOf(" ")).trim(); // Everything up to the end of the attribute type;
if(strTemp.lastIndexOf(" ") < 0) {propM.put("type", strTemp); // Describe the start of the attribute type
}else{ // Indicates that there are modifiers in front of the attribute type
if(s.indexOf("final ") > -1) {propM.put("isFinal", "1");}
propM.put("type", strTemp.substring(strTemp.lastIndexOf(" ") + 1));
}
if(s.indexOf("//") > -1){propM.put("remark", s.substring(s.indexOf("//") + 2).trim() );} // with comments
l.add(propM);
m.put(classNameL.get(lv - 1), l);
}
if(s.indexOf("(") > 0 & amp; & amp; s.indexOf(")") > 0 & amp; & amp; s.indexOf("{") > 0 ) {func = true;}
if(s.indexOf("}") > -1) {
if(func) {func = false;}else {classNameL.remove(classNameL.size() - 1);lv--;}
} // In order to keep all properties close together without being separated by getter and setter methods, the getters and setters are inserted uniformly in the second loop.
}
StringBuffer rs = new StringBuffer();
String tab = "";
for(String s : sL) {
if(s.indexOf("package ") > -1 || s.indexOf("import ") > -1 || "".equals(s.trim())
|| s.indexOf(";") > 0 & amp; & amp; s.indexOf("this.") < 0 & amp; & amp; s.indexOf("return ") < 0) {rs.append(s + "\r\\
");}
if(s.indexOf("class ") > -1 & amp; & amp; s.indexOf("{") > s.indexOf("class ")) { // It is a class
classNameL.add(s.substring(s.indexOf("class ") + 6, s.indexOf("{")).trim()); // Get the class name
if(s.indexOf("//") > -1) {rs.append(tab + "/**" + s.substring(s.indexOf("//") + 2) .trim() + "*/\r\\
");}
lv + + ;rs.append(s + "\r\\
");}
if(s.indexOf("(") > 0 & amp; & amp; s.indexOf(")") > 0 & amp; & amp; s.indexOf("{") > 0 ) {func = true;}
if(s.indexOf("}") > -1) {
if(func) {func = false;continue;}
List<Map<String, String>> l = m.get(classNameL.get(lv - 1));
if(l != null) {
for(Map<String, String> p : l) {
if(p.get("remark") != null) { // The current attribute has comments
rs.append(tab + "/**Get: " + p.get("remark") + (p.get("value") != null ? " | Default value: " + p.get("value") : "") + "*/\r\\
");
}
rs.append(tab + "public " + p.get("type") + " get" + p.get("name").substring(0, 1).toUpperCase()
+ p.get("name").substring(1) + "(){return " + p.get("name") + ";}\r\\
") ; // getter method
if(p.get("isFinal") != null) {continue;} // There is final modification (set method is not allowed)
if(p.get("remark") != null) {
rs.append(tab + "/** Setting: " + p.get("remark") + (p.get("value") != null ? " | Default value: " + p.get("value") : "") + "*/\r\\
");
}
rs.append(tab + "public " + classNameL.get(lv - 1) + " set" + p.get("name").substring(0, 1).toUpperCase()
+ p.get("name").substring(1) + "(" + p.get("type") + " " + p.get("name") + "){this."
+ p.get("name") + "=" + p.get("name") + ";return this;}\r\\
"); // setter method
}
}
classNameL.remove(classNameL.size() - 1); lv--; rs.append(s + "\r\\
");
}
tab = "";
for(int i=0;;i + + ) {
if(s.length() > i + 1 & amp; & amp; s.charAt(i) == '\t') {tab + = "\t";}else{break; }
}
}
fw = new FileWriter(path, false);
fw.write(rs.toString());
} catch (IOException e) {e.printStackTrace();}
if(fw != null) {try {fw.close();} catch (IOException e) {}}
}
}

The above code is the generation tool. Specify the corresponding entity class file path in the path variable, and executing the code will automatically generate comments in the entity class.

Demonstration example

Suppose we have a student entity class Student, the code is as follows:

package com.po;

import java.util.List;

public class Student <T> { // Student entity class
private Integer id; // in10-student id, primary key increases automatically
public int type = 1; // ti1-student type: 1 general student, 2 science student, 3 liberal arts student, 4 art student, 5 physical education student
protected String name; // va4-student name (no more than 4 characters)
private static boolean isGirl;
Score score; // Score score
private static final double num = Math.E;
public class Score{ // Score score entity class
private Integer chinese; // Chinese score
private Integer maths; // math scores
private Integer art = 60; // Art score
}
private List<Experience> expL; //Practical experience
class Experience{
private Integer id; // Experienced id
private Event event; // things experienced
protected class Event {
private Long time; // The time when things started
private String describe; // description of what happened
private String result; // The result and evaluation of the matter
}
}
private List<String> hobbyL; // students' hobbies
private T t;
}

There are various types of data in this entity class, including inner classes and generics.

If you use the IDE to automatically generate getters and setters (Source – Generate Getters and Setters…), there will be no comments. Simple entity classes are okay, but if it is a complex entity class, there are dozens or even hundreds of attributes, or there are complex attributes, and there is no way to tell what the value is directly from the attribute name (such as in the example) type attribute, what does 1 represent, what does 2 represent…), you will inevitably forget it after a long time. At this time, we use the tool method to directly generate getter, setter methods and annotations. After running the tool method, the entity class Student changes as follows:

package com.po;

import java.util.List;

/**Student entity class*/
public class Student <T> { // Student entity class
private Integer id; // in10-student id, primary key increases automatically
public int type = 1; // ti1-student type: 1 general student, 2 science student, 3 liberal arts student, 4 art student, 5 physical education student
protected String name; // va4-student name (no more than 4 characters)
private static boolean isGirl;
Score score; // Score score
private static final double num = Math.E;
/**Score Entity Class*/
public class Score{ // Score score entity class
private Integer chinese; // Chinese score
private Integer maths; // math scores
private Integer art = 60; // Art score
/**Get: Chinese score*/
public Integer getChinese(){return chinese;}
/**Settings: Chinese scores*/
public Score setChinese(Integer chinese){this.chinese=chinese;return this;}
/**Get: math scores*/
public Integer getMaths(){return maths;}
/**Settings: Math Score*/
public Score setMaths(Integer maths){this.maths=maths;return this;}
/**Get: Art score | Default value: 60*/
public Integer getArt(){return art;}
/**Settings: Art Score | Default: 60*/
public Score setArt(Integer art){this.art=art;return this;}
}
private List<Experience> expL; //Practical experience
class Experience{
private Integer id; // Experienced id
private Event event; // things experienced
protected class Event {
private Long time; // The time when things started
private String describe; // description of what happened
private String result; // The result and evaluation of the matter
/**Get: the time when the thing started*/
public Long getTime(){return time;}
/**Settings: Time when things start*/
public Event setTime(Long time){this.time=time;return this;}
/**Get: description of what happened*/
public String getDescribe(){return describe;}
/**Settings: Description of what happened*/
public Event setDescribe(String describe){this.describe=describe;return this;}
/**Get: the result and evaluation of the matter*/
public String getResult(){return result;}
/**Settings: Results and evaluation of things*/
public Event setResult(String result){this.result=result;return this;}
}
/**Get: experience id*/
public Integer getId(){return id;}
/**Settings: Experienced ID*/
public Experience setId(Integer id){this.id=id;return this;}
/**Get: Experienced things*/
public Event getEvent(){return event;}
/**Settings: Things experienced*/
public Experience setEvent(Event event){this.event=event;return this;}
}
private List<String> hobbyL; // students' hobbies
private T t;
/**Get: in10-student id, primary key auto-increment*/
public Integer getId(){return id;}
/**Settings: in10-student id, primary key auto-increment*/
public Student <T> setId(Integer id){this.id=id;return this;}
/**Get: ti1-student type: 1 general student, 2 science student, 3 liberal arts student, 4 art student, 5 physical education student | Default value: 1*/
public int getType(){return type;}
/**Settings: ti1-student type: 1 general student, 2 science student, 3 liberal arts student, 4 art student, 5 physical education student | Default value: 1*/
public Student <T> setType(int type){this.type=type;return this;}
/**Get: va4-student name (no more than 4 characters)*/
public String getName(){return name;}
/**Settings: va4-student name (no more than 4 characters)*/
public Student <T> setName(String name){this.name=name;return this;}
public boolean getIsGirl(){return isGirl;}
public Student <T> setIsGirl(boolean isGirl){this.isGirl=isGirl;return this;}
/**Get: Score*/
public Score getScore(){return score;}
/**Settings: Grade Score*/
public Student <T> setScore(Score score){this.score=score;return this;}
public double getNum(){return num;}
/**Get: practical experience*/
public List<Experience> getExpL(){return expL;}
/**Settings: Practical experience*/
public Student <T> setExpL(List<Experience> expL){this.expL=expL;return this;}
/**Get: student hobbies*/
public List<String> getHobbyL(){return hobbyL;}
/**Settings: Student Hobbies*/
public Student <T> setHobbyL(List<String> hobbyL){this.hobbyL=hobbyL;return this;}
public T getT(){return t;}
public Student <T> setT(T t){this.t=t;return this;}
}

Screenshot of effect

In fact, it is to add [/** xxx */] comments. The content of the comments is the content after [//] after each class name or each attribute. What are the benefits of this annotation?

The benefits are obvious. If you find that the annotation is wrong after generating it, or the annotation needs to change in the future, you only need to modify the content of the annotation after the corresponding double slash, and then directly run this tool method again to regenerate the getter and setter annotations. (No need to delete the original getter and setter annotations.)

Rules and Restrictions

(1) The generated getter and setter methods are public, no other logic is added, and the method itself has no line breaks. If the methods or comments you want to generate need to be changed, processed or beautified, please modify the comments marked [//getter method], [//setter method] and [rs.append(tab + “/**Get:\ “], [rs.append(tab + “/**setting:”].

(2) Although the generated getter and setter methods do not have line breaks, please pay attention to line breaks for the attributes in the class. Do not write the attribute declaration together with the class declaration [public class…], class terminator [}] and other attributes. within one line, otherwise an error will occur when running the method.

(3) All class or attribute comments must be written with a double slash [//] at the end of the corresponding line, and line breaks are not supported. No matter how long the comment is, it must be written on the same line. Moreover, this tool does not determine whether the attribute is commented out. Even if the properties are commented out (for example: [// private String name2;]), this tool will still generate getter and setter methods.

(4) This tool method will only retain the package path [package…], class reference [import…], blank line, class or method declaration, and class terminator [in this example (entity class Student) }]. All other content will be deleted when running this tool method. For example, document comments [/** xxx */] or paragraph comments [/* xxx */] written by you, as well as other methods written by you (such as constructor methods, toString() methods, etc.). It is not recommended that you write any other methods in this entity class because it can easily cause errors when the current tool is run.

(5) Since this tool splits each part according to spaces, there should be no spaces in the attribute type, otherwise the generated getter and setter methods will be wrong. For example, [private Map data;], because there is a space after [,] in the attribute type [Map] and in front of [Object], an error will occur. Just remove this space.

(Note: In this example, a warning will appear in the generated entity class Student because the isGirl attribute is statically modified. This.isGirl should not be used in the setter method. Student.isGirl should be used. However, this The keyword here originally represents the current class Student. Using this.isGirl will not cause problems, so the author of this warning does not intend to fix it. Friends with obsessive-compulsive disorder should modify the tool class by themselves or manually modify the setter method after generation.)

Solemn declaration

Because this tool method directly modifies the content of the original entity class, please make a backup of the original entity class before running this tool method. Once there are any omissions or errors in this software that cause the data in your original entity class to be damaged or lost and cannot be restored, the author does not assume any responsibility for the losses caused to you.

(Tip: If the modified entity class is open in the IDE, if you find any problems after using this tool to modify it, you can press ctrl + z in the entity class window to undo it and return to the previous state.)

The method is explained here. I hope this small tool can help everyone.

Although this example has considered as many situations as possible, due to the ever-changing content of entity classes, the author cannot take them all into consideration. If there are any omissions or hidden dangers in the method, please feel free to enlighten me.