2016년 4월 1일 금요일

lombok 설치 및 정보 관련 이런저런


설치 순서
1. http://projectlombok.org/download.html 에서 lombok.jar 를 다운로드
2. java -jar 경로/lombok.jar
3. lombok.jar 실행하여 IDE 에 등록
    • java -jar lombok.jar
    • IDE를 못 찾는경우 수동으로 등록을 해줘야 한다.
IDE를 못 찾는 경우
    • 명시적으로 설치
    • 추가할 eclipse 실행파일 선택하고 install/update 실행


3. maven 연계
pom.xml 추가
<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.12.6</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

4. 사용
  • val
Finally! Hassle-free final local variables.
  • @NonNull
or: How I learned to stop worrying and love the NullPointerException.

With Lombok

01 import lombok.NonNull;
02 
03 public class NonNullExample extends Something {
04   private String name;
05   
06   public NonNullExample(@NonNull Person person) {
07     super("Hello");
08     this.name = person.getName();
09   }
10 }

Vanilla Java

01 import lombok.NonNull;
02 
03 public class NonNullExample extends Something {
04   private String name;
05   
06   public NonNullExample(@NonNull Person person) {
07     super("Hello");
08     if (person == null) {
09       throw new NullPointerException("person");
10     }
11     this.name = person.getName();
12   }
13 }






















  • @Cleanup
Automatic resource management: Call your close() methods safely with no hassle.

With Lombok

01 import lombok.Cleanup;
02 import java.io.*;
03 
04 public class CleanupExample {
05   public static void main(String[] argsthrows IOException {
06     @Cleanup InputStream in = new FileInputStream(args[0]);
07     @Cleanup OutputStream out = new FileOutputStream(args[1]);
08     byte[] b = new byte[10000];
09     while (true) {
10       int r = in.read(b);
11       if (r == -1break;
12       out.write(b, 0, r);
13     }
14   }
15 }

Vanilla Java

01 import java.io.*;
02 
03 public class CleanupExample {
04   public static void main(String[] argsthrows IOException {
05     InputStream in = new FileInputStream(args[0]);
06     try {
07       OutputStream out = new FileOutputStream(args[1]);
08       try {
09         byte[] b = new byte[10000];
10         while (true) {
11           int r = in.read(b);
12           if (r == -1break;
13           out.write(b, 0, r);
14         }
15       finally {
16         if (out != null) {
17           out.close();
18         }
19       }
20     finally {
21       if (in != null) {
22         in.close();
23       }
24     }
25   }
26 }



































  • @Getter / @Setter
Never write public int getFoo() {return foo;} again.

생략...

  • @ToString
No need to start a debugger to see your fields: Just let lombok generate a toString for you!


With Lombok

01 import lombok.ToString;
02 
03 @ToString(exclude="id")
04 public class ToStringExample {
05   private static final int STATIC_VAR = 10;
06   private String name;
07   private Shape shape = new Square(510);
08   private String[] tags;
09   private int id;
10   
11   public String getName() {
12     return this.getName();
13   }
14   
15   @ToString(callSuper=true, includeFieldNames=true)
16   public static class Square extends Shape {
17     private final int width, height;
18     
19     public Square(int width, int height) {
20       this.width = width;
21       this.height = height;
22     }
23   }
24 }

Vanilla Java

01 import java.util.Arrays;
02 
03 public class ToStringExample {
04   private static final int STATIC_VAR = 10;
05   private String name;
06   private Shape shape = new Square(510);
07   private String[] tags;
08   private int id;
09   
10   public String getName() {
11     return this.getName();
12   }
13   
14   public static class Square extends Shape {
15     private final int width, height;
16     
17     public Square(int width, int height) {
18       this.width = width;
19       this.height = height;
20     }
21     
22     @Override public String toString() {
23       return "Square(super=" super.toString() ", width=" this.width + ", height=" this.height + ")";
24     }
25   }
26   
27   @Override public String toString() {
28     return "ToStringExample(" this.getName() ", " this.shape + ", " + Arrays.deepToString(this.tags")";
29   }
30 }











































  • @EqualsAndHashCode
Equality made easy: Generates hashCode and equals implementations from the fields of your object.

With Lombok

01 import lombok.EqualsAndHashCode;
02 
03 @EqualsAndHashCode(exclude={"id""shape"})
04 public class EqualsAndHashCodeExample {
05   private transient int transientVar = 10;
06   private String name;
07   private double score;
08   private Shape shape = new Square(510);
09   private String[] tags;
10   private int id;
11   
12   public String getName() {
13     return this.name;
14   }
15   
16   @EqualsAndHashCode(callSuper=true)
17   public static class Square extends Shape {
18     private final int width, height;
19     
20     public Square(int width, int height) {
21       this.width = width;
22       this.height = height;
23     }
24   }
25 }

Vanilla Java

01 import java.util.Arrays;
02 
03 public class EqualsAndHashCodeExample {
04   private transient int transientVar = 10;
05   private String name;
06   private double score;
07   private Shape shape = new Square(510);
08   private String[] tags;
09   private int id;
10   
11   public String getName() {
12     return this.name;
13   }
14   
15   @Override public boolean equals(Object o) {
16     if (o == thisreturn true;
17     if (!(instanceof EqualsAndHashCodeExample)) return false;
18     EqualsAndHashCodeExample other = (EqualsAndHashCodeExampleo;
19     if (!other.canEqual((Object)this)) return false;
20     if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
21     if (Double.compare(this.score, other.score!= 0return false;
22     if (!Arrays.deepEquals(this.tags, other.tags)) return false;
23     return true;
24   }
25   
26   @Override public int hashCode() {
27     final int PRIME = 59;
28     int result = 1;
29     final long temp1 = Double.doubleToLongBits(this.score);
30     result = (result*PRIME(this.name == null 43 this.name.hashCode());
31     result = (result*PRIME(int)(temp1 ^ (temp1 >>> 32));
32     result = (result*PRIME+ Arrays.deepHashCode(this.tags);
33     return result;
34   }
35   
36   protected boolean canEqual(Object other) {
37     return other instanceof EqualsAndHashCodeExample;
38   }
39   
40   public static class Square extends Shape {
41     private final int width, height;
42     
43     public Square(int width, int height) {
44       this.width = width;
45       this.height = height;
46     }
47     
48     @Override public boolean equals(Object o) {
49       if (o == thisreturn true;
50       if (!(instanceof Square)) return false;
51       Square other = (Squareo;
52       if (!other.canEqual((Object)this)) return false;
53       if (!super.equals(o)) return false;
54       if (this.width != other.widthreturn false;
55       if (this.height != other.heightreturn false;
56       return true;
57     }
58     
59     @Override public int hashCode() {
60       final int PRIME = 59;
61       int result = 1;
62       result = (result*PRIMEsuper.hashCode();
63       result = (result*PRIMEthis.width;
64       result = (result*PRIMEthis.height;
65       return result;
66     }
67     
68     protected boolean canEqual(Object other) {
69       return other instanceof Square;
70     }
71   }
72 }








































































  • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor
Constructors made to order: Generates constructors that take no arguments, one argument per final / non-null field, or one argument for every field.



With Lombok

01 import lombok.AccessLevel;
02 import lombok.RequiredArgsConstructor;
03 import lombok.AllArgsConstructor;
04 import lombok.NonNull;
05 
06 @RequiredArgsConstructor(staticName = "of")
07 @AllArgsConstructor(access = AccessLevel.PROTECTED)
08 public class ConstructorExample<T> {
09   private int x, y;
10   @NonNull private T description;
11   
12   @NoArgsConstructor
13   public static class NoArgsExample {
14     @NonNull private String field;
15   }
16 }

Vanilla Java

01 public class ConstructorExample<T> {
02   private int x, y;
03   @NonNull private T description;
04   
05   private ConstructorExample(T description) {
06     if (description == nullthrow new NullPointerException("description");
07     this.description = description;
08   }
09   
10   public static <T> ConstructorExample<T> of(T description) {
11     return new ConstructorExample<T>(description);
12   }
13   
14   @java.beans.ConstructorProperties({"x""y""description"})
15   protected ConstructorExample(int x, int y, T description) {
16     if (description == nullthrow new NullPointerException("description");
17     this.x = x;
18     this.y = y;
19     this.description = description;
20   }
21   
22   public static class NoArgsExample {
23     @NonNull private String field;
24     
25     public NoArgsExample() {
26     }
27   }
28 }



































  • @Data
All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields, and @RequiredArgsConstructor!



With Lombok

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.PACKAGEprivate 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 }

Vanilla Java

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 == thisreturn true;
051     if (!(instanceof DataExample)) return false;
052     DataExample other = (DataExampleo;
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()) != 0return 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 43 this.getName().hashCode());
066     result = (result*PRIMEthis.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 == thisreturn true;
103       if (!(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 43 this.getName().hashCode());
115       result = (result*PRIME(this.getValue() == null 43 this.getValue().hashCode());
116       return result;
117     }
118   }
119 }



































































































  • @Value
Immutable classes made very easy.

With Lombok

01 import lombok.AccessLevel;
02 import lombok.experimental.NonFinal;
03 import lombok.experimental.Value;
04 import lombok.experimental.Wither;
05 import lombok.ToString;
06 
07 @Value public class ValueExample {
08   String name;
09   @Wither(AccessLevel.PACKAGE@NonFinal int age;
10   double score;
11   protected String[] tags;
12   
13   @ToString(includeFieldNames=true)
14   @Value(staticConstructor="of")
15   public static class Exercise<T> {
16     String name;
17     T value;
18   }
19 }

Vanilla Java

001 import java.util.Arrays;
002 
003 public final class ValueExample {
004   private final String name;
005   private int age;
006   private final double score;
007   protected final String[] tags;
008   
009   @java.beans.ConstructorProperties({"name""age""score""tags"})
010   public ValueExample(String name, int age, double score, String[] tags) {
011     this.name = name;
012     this.age = age;
013     this.score = score;
014     this.tags = tags;
015   }
016   
017   public String getName() {
018     return this.name;
019   }
020   
021   public int getAge() {
022     return this.age;
023   }
024   
025   public double getScore() {
026     return this.score;
027   }
028   
029   public String[] getTags() {
030     return this.tags;
031   }
032   
033   @java.lang.Override
034   public boolean equals(Object o) {
035     if (o == thisreturn true;
036     if (!(instanceof ValueExample)) return false;
037     final ValueExample other = (ValueExample)o;
038     final Object this$name = this.getName();
039     final Object other$name = other.getName();
040     if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
041     if (this.getAge() != other.getAge()) return false;
042     if (Double.compare(this.getScore(), other.getScore()) != 0return false;
043     if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
044     return true;
045   }
046   
047   @java.lang.Override
048   public int hashCode() {
049     final int PRIME = 59;
050     int result = 1;
051     final Object $name = this.getName();
052     result = result * PRIME + ($name == null 43 : $name.hashCode());
053     result = result * PRIME + this.getAge();
054     final long $score = Double.doubleToLongBits(this.getScore());
055     result = result * PRIME + (int)($score >>> 32 ^ $score);
056     result = result * PRIME + Arrays.deepHashCode(this.getTags());
057     return result;
058   }
059   
060   @java.lang.Override
061   public String toString() {
062     return "ValueExample(name=" + getName() ", age=" + getAge() ", score=" + getScore() ", tags=" + Arrays.deepToString(getTags()) ")";
063   }
064   
065   ValueExample withAge(int age) {
066     return this.age == age ? this new ValueExample(name, age, score, tags);
067   }
068   
069   public static final class Exercise<T> {
070     private final String name;
071     private final T value;
072     
073     private Exercise(String name, T value) {
074       this.name = name;
075       this.value = value;
076     }
077     
078     public static <T> Exercise<T> of(String name, T value) {
079       return new Exercise<T>(name, value);
080     }
081     
082     public String getName() {
083       return this.name;
084     }
085     
086     public T getValue() {
087       return this.value;
088     }
089     
090     @java.lang.Override
091     public boolean equals(Object o) {
092       if (o == thisreturn true;
093       if (!(instanceof ValueExample.Exercise)) return false;
094       final Exercise<?> other = (Exercise<?>)o;
095       final Object this$name = this.getName();
096       final Object other$name = other.getName();
097       if (this$name == null ? other$name != null : !this$name.equals(other$name)) return false;
098       final Object this$value = this.getValue();
099       final Object other$value = other.getValue();
100       if (this$value == null ? other$value != null : !this$value.equals(other$value)) return false;
101       return true;
102     }
103     
104     @java.lang.Override
105     public int hashCode() {
106       final int PRIME = 59;
107       int result = 1;
108       final Object $name = this.getName();
109       result = result * PRIME + ($name == null 43 : $name.hashCode());
110       final Object $value = this.getValue();
111       result = result * PRIME + ($value == null 43 : $value.hashCode());
112       return result;
113     }
114     
115     @java.lang.Override
116     public String toString() {
117       return "ValueExample.Exercise(name=" + getName() ", value=" + getValue() ")";
118     }
119   }
120 }



































































































  • @Builder
... and Bob's your uncle: No-hassle fancy-pants APIs for object creation!

With Lombok

01 import lombok.Builder;
02 import lombok.Singular;
03 import java.util.Set;
04 
05 @Builder
06 public class BuilderExample {
07   private String name;
08   private int age;
09   @Singular private Set<String> occupations;
10 }

Vanilla Java

01 import java.util.Set;
02 
03 public class BuilderExample {
04   private String name;
05   private int age;
06   private Set<String> occupations;
07   
08   BuilderExample(String name, int age, Set<String> occupations) {
09     this.name = name;
10     this.age = age;
11     this.occupations = occupations;
12   }
13   
14   public static BuilderExampleBuilder builder() {
15     return new BuilderExampleBuilder();
16   }
17   
18   public static class BuilderExampleBuilder {
19     private String name;
20     private int age;
21     private java.util.ArrayList<String> occupations;
22     
23     BuilderExampleBuilder() {
24     }
25     
26     public BuilderExampleBuilder name(String name) {
27       this.name = name;
28       return this;
29     }
30     
31     public BuilderExampleBuilder age(int age) {
32       this.age = age;
33       return this;
34     }
35     
36     public BuilderExampleBuilder occupation(String occupation) {
37       if (this.occupations == null) {
38         this.occupations = new java.util.ArrayList<String>();
39       }
40       
41       this.occupations.add(occupation);
42       return this;
43     }
44     
45     public BuilderExampleBuilder occupations(Collection<? extends String> occupations) {
46       if (this.occupations == null) {
47         this.occupations = new java.util.ArrayList<String>();
48       }
49 
50       this.occupations.addAll(occupations);
51       return this;
52     }
53     
54     public BuilderExampleBuilder clearOccupations() {
55       if (this.occupations != null) {
56         this.occupations.clear();
57       }
58       
59       return this;
60     }
61 
62     public BuilderExample build() {
63       // complicated switch statement to produce a compact properly sized immutable set omitted.
64       // go to https://projectlombok.org/features/Singular-snippet.html to see it.
65       Set<String> occupations = ...;
66       return new BuilderExample(name, age, occupations);
67     }
68     
69     @java.lang.Override
70     public String toString() {
71       return "BuilderExample.BuilderExampleBuilder(name = " this.name + ", age = " this.age + ", occupations = " this.occupations + ")";
72     }
73   }
74 }































































  • @SneakyThrows
To boldly throw checked exceptions where no one has thrown them before!



  • @Synchronized
synchronized done right: Don't expose your locks.



  • @Getter(lazy=true)
Laziness is a virtue!



  • @Log
Captain's Log, stardate 24435.7: "What was that line again?"

With Lombok

01 import lombok.extern.java.Log;
02 import lombok.extern.slf4j.Slf4j;
03 
04 @Log
05 public class LogExample {
06   
07   public static void main(String... args) {
08     log.error("Something's wrong here");
09   }
10 }
11 
12 @Slf4j
13 public class LogExampleOther {
14   
15   public static void main(String... args) {
16     log.error("Something else is wrong here");
17   }
18 }
19 
20 @CommonsLog(topic="CounterLog")
21 public class LogExampleCategory {
22 
23   public static void main(String... args) {
24     log.error("Calling the 'CounterLog' with a message");
25   }
26 }

Vanilla Java

01 public class LogExample {
02   private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
03   
04   public static void main(String... args) {
05     log.error("Something's wrong here");
06   }
07 }
08 
09 public class LogExampleOther {
10   private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);
11   
12   public static void main(String... args) {
13     log.error("Something else is wrong here");
14   }
15 }
16 
17 public class LogExampleCategory {
18   private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog");
19 
20   public static void main(String... args) {
21     log.error("Calling the 'CounterLog' with a message");
22   }
23 }


  • val
불변의 지역변수를 만들 수 있습니다. 현재 val은 필드에는 적용되지 않고 지역 변수에만 적용됩니다. final를 붙인 것과 비슷한 효과를 갖어옵니다. 또한 val은 타입을 유추하기 때문에 타입을 따로 쓰지 않고 지역변수를 선언할 수 있습니다.



댓글 1개:

  1. 안녕하세요
    저는 라이언로켓이라는 스타트업에 다니는 정승환이라고 합니다.

    블로그 내용들을 보다가, 제안드리고 싶은 부분이 있어서
    이렇게 댓글 남깁니다.
    혹시나 "온라인 강의" 에 대해서 관심이 있으시면
    hwan@lionrocket.ai로
    메일 한 번 주실 수 있으실까요?
    메일로 자세한 내용 나누고 싶습니다

    감사합니다.
    좋은 하루되세요 :)

    답글삭제