반응형
Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

웹풀스택 공부 중

15 - 1. Java - Lombok 본문

웹개발/Java

15 - 1. Java - Lombok

lukeit 2024. 11. 4. 13:08

Java의 동작 원리

  • 3가지만 기억하자
    • Java (Source Code: 내가 작성한 코드) → AST (Abstract Syntax Tree: 문법을 트리형태로 만들어준다) → Binary Code (Machine Language: AST를 해석해서 Machine Language로 변환하여 실행한다)

Lombok 동작 원리

  • Lombok: Annotation Processor이다
    • Annotation Processor가 Source code를 읽고, 코드를 대신 작성해준다
      • Source Code, AST, Binary Code에 전부 코드 추가 및 수정이 가능하다
  • Lombok은 AST에다가 코드를 주입해준다
    • “자식”으로 붙여준다
  • Compile 시점에 Annotation Processor를 사용해 Source code의 AST를 조작해준다
    • 그 이후, Javac (Java Compiler)에 AST기반으로 Byte Code를 생성한다

Common Lombok Annotations

필드나 Class에 둘중 원하는곳에 넣을 수 있다

  • @AllArgsConstructor : 해당 객체의 생성자 생성 (모든 인자의 생성자를 만든다)

    • @AllArgsConstructor(access = AccessLevel.PRIVATE) 이런식으로 접근 제어자를 설정 가능
  • @Getter / @Setter : 해당 필드에 대해 get() / set() 메서드 생성

    • 무지성으로 클래스에 이것들을 적용하지 말자!

      • 필드마다 접근 및 수정을 여는것이 “정말 필요한것인지” 생각해보고 적용하는게 좋다
    • 있는것과 없는것을 비교해보자

      @AllArgsConstructor
      class Person {
      
        private String name;
      
        private int age;
      
        public String getName() { return this.name; }
        public int getAge() { return this.age; }
        public void setName(String name) { this.name = name; }
        public void setAge(int age) { this.age = age;}
      }
      
      // @Getter, @Setter 사용 후
      @AllArgsConstructor
      class Person {
        @Getter
        @Setter
        private String name;
        @Getter
        @Setter
        private int age;
      }
    • 값을 설정할 수 있는 3가지 방법

      • Constructor를 통해 값을 지정해주기
      • Setter로 계속 수정하기
        • 이 방법은 불변성을 위배하기에 추천하지 않는다
      • @RequiredArgsConstructor 를 사용하기
        • 생성 후 값이 바뀌지 않도록 한다
        • Setter를 통해서 값을 바꿀 수 없으며 final 이 붙어있는 field를 생성한다
          • 초기화할때만 값을 지정할 수 있다
        • 나중에 설정해도 되는 다른 필드들은 @Setter 를 따로 붙여서 가변성을 부여할 수 있다
        • Spring Bean 객체를 주입받아 사용할때 이것을 써서 주로 사용한다
  • @ToString : 해당 객체에 대해 toString() 메서드 생성

    • 따로 구현할 필요없이 깔끔하게 출력해준다!
    • 단순하게 필드 노출에 사용되지만, 옵션을 통해 세부 조율이 가능하다
      • field 단위로 노출을 제외시키고 싶을 때
        • @ToString.Exclude
      • class단위로 특정 field의 노출을 제외시키고 싶을 때
        • @ToString(exclude = "email"): 하나의 필드만 제외시키거나
        • @ToString(exclude = {"email, "age"}) : 이런식으로 여러개를 제외시킬 수도 있다
      • class단위로 하나만 노출시키고 싶을때
        • @ToString(of = {"name"})
      • 상속받은 class에서도 부모의 값을 호출하고 싶을때
        • @ToString(callSuper = True)
          • 하지만 이것만 한다면 부모의 주소값이 나온다
            • 부모에서 ToString을 사용하지 않아서 그렇다!
  • @EqualsAndHashCode : 객체의 동등성 비교를 위해 사용한다

    • Java에서 동등성 비교하는 방법 두가지

      • == : Primitive Type에 대한 동등성을 비교할 수 있다

        • 0~127까지의 숫자들은 자주 쓰이기에 JVM 최적화를 통해 미리 객체를 만들어놓고, 매번 재활용하기에 == 을 사용해 비교가 가능은 하다
      • equals : Reference Type에 대한 동등성 비교

        • 객체 비교는 항상 이것을 사용하자!

        • sout(reference_a.equals(reference_b))

                Member aaron = new Member(1, "A", 10, "A@example.com");
                Member aaron2 = new Member(1, "A", 10, "A@example.com");
          
                System.out.println(aaron == aaron2);
                System.out.println(aaron.equals(aaron2));
                // False 로 뜨는 이유는 어떤 필드값을 비교할지 정의를 하지 않아서 그렇다
      • 하지만 비교하고자 하는 필드가 엄청 많다면?

        • Hash 값을 만들면 된다!

        • @EqualsAndHashCode(of = {"id", "name")} 이런식으로 어떤 필드를 기반으로 생성할지 지정할 수 있다

        • @EqualsAndHashCode(exclude = {"age", "email"}) 이런식으로 반대로 어떤 필드를 뺄지 지정할 수 있다

        • @EqualsAndHashCode(callSuper = true) 로 상속받은 것도 같이 비교할 수 있다

          @EqualsAndHashCode(of = {"id", "name"})
          public class Person {
            private int id;
            private String name;
            private int age;
            private String email;
          
            // 생성자, 게터, 세터 생략
          }
  • @FieldDefaults : 필드에 대한 접근제어자 일괄 적용

    • @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
      • 이런식으로 Field에 대한 default setting을 private final 로 명시할 필요 없이 만들어줄 수 있다
반응형