This gives a lot of code, which is not very interesting to write and maintain, but for the sake of java bean (and other reasons) you will do it correctly.
It's one of the features of the IDE that you can let them generate the proper getter/setter methods.
Usually it's called something like "Encapsulate property access". You then select the properties you wish setter/getter created and you are done, the idea puts the correct code in your class.
Nice, but, it could be simpler.
The drawback of all this is, that you fill up your class file with a lot of set/get code which you usually don't want to see.
Fortunally there is help for this as well.
Look at the project Lombook.
With this project you write your class like this:
01 import lombok.AccessLevel;
02 import lombok.Setter;
03 import lombok.Data;
04 import lombok.ToString;
05
06 @Data public class DataExample {
07 private final String name;
08 @Setter(AccessLevel.PACKAGE) private int age;
09 private double score;
10 private String[] tags;
11
12 @ToString(includeFieldNames=true)
13 @Data(staticConstructor="of")
14 public static class Exercise<T> {
15 private final String name;
16 private final T value;
17 }
18 }
These 18 lines of code do the same as these 118 lines of plain java coding:
001 import java.util.Arrays;
002
003 public class DataExample {
004 private final String name;
005 private int age;
006 private double score;
007 private String[] tags;
008
009 public DataExample(String name) {
010 this.name = name;
011 }
012
013 public String getName() {
014 return this.name;
015 }
016
017 void setAge(int age) {
018 this.age = age;
019 }
020
021 public int getAge() {
022 return this.age;
023 }
024
025 public void setScore(double score) {
026 this.score = score;
027 }
028
029 public double getScore() {
030 return this.score;
031 }
032
033 public String[] getTags() {
034 return this.tags;
035 }
036
037 public void setTags(String[] tags) {
038 this.tags = tags;
039 }
040
041 @Override public String toString() {
042 return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";
043 }
044
045 protected boolean canEqual(Object other) {
046 return other instanceof DataExample;
047 }
048
049 @Override public boolean equals(Object o) {
050 if (o == this) return true;
051 if (!(o instanceof DataExample)) return false;
052 DataExample other = (DataExample) o;
053 if (!other.canEqual((Object)this)) return false;
054 if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
055 if (this.getAge() != other.getAge()) return false;
056 if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
057 if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
058 return true;
059 }
060
061 @Override public int hashCode() {
062 final int PRIME = 59;
063 int result = 1;
064 final long temp1 = Double.doubleToLongBits(this.getScore());
065 result = (result*PRIME) + (this.getName() == null ? 0 : this.getName().hashCode());
066 result = (result*PRIME) + this.getAge();
067 result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
068 result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
069 return result;
070 }
071
072 public static class Exercise<T> {
073 private final String name;
074 private final T value;
075
076 private Exercise(String name, T value) {
077 this.name = name;
078 this.value = value;
079 }
080
081 public static <T> Exercise<T> of(String name, T value) {
082 return new Exercise<T>(name, value);
083 }
084
085 public String getName() {
086 return this.name;
087 }
088
089 public T getValue() {
090 return this.value;
091 }
092
093 @Override public String toString() {
094 return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";
095 }
096
097 protected boolean canEqual(Object other) {
098 return other instanceof Exercise;
099 }
100
101 @Override public boolean equals(Object o) {
102 if (o == this) return true;
103 if (!(o instanceof Exercise)) return false;
104 Exercise<?> other = (Exercise<?>) o;
105 if (!other.canEqual((Object)this)) return false;
106 if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;
107 if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;
108 return true;
109 }
110
111 @Override public int hashCode() {
112 final int PRIME = 59;
113 int result = 1;
114 result = (result*PRIME) + (this.getName() == null ? 0 : this.getName().hashCode());
115 result = (result*PRIME) + (this.getValue() == null ? 0 : this.getValue().hashCode());
116 return result;
117 }
118 }
119 }
So with project lombok you can concentrate on the real code, and the annotations do expand on build to the boilerplate code.
There are many options in lombok to also generate other things for java classes, be sure to look at the documentation.
There is just one "bad" thing about it:
By definition annotations should not create java code, but in this case I think it is worth the "break" of rules.
There are many options in lombok to also generate other things for java classes, be sure to look at the documentation.
There is just one "bad" thing about it:
By definition annotations should not create java code, but in this case I think it is worth the "break" of rules.
No comments:
Post a Comment