웹풀스택 공부 중
15 - 1. Java - Lombok 본문
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에 전부 코드 추가 및 수정이 가능하다
- Annotation Processor가 Source 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을 사용하지 않아서 그렇다!
- 하지만 이것만 한다면 부모의 주소값이 나온다
- field 단위로 노출을 제외시키고 싶을 때
@EqualsAndHashCode
: 객체의 동등성 비교를 위해 사용한다Java에서 동등성 비교하는 방법 두가지
==
: Primitive Type에 대한 동등성을 비교할 수 있다- 0~127까지의 숫자들은 자주 쓰이기에 JVM 최적화를 통해 미리 객체를 만들어놓고, 매번 재활용하기에
==
을 사용해 비교가 가능은 하다
- 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
로 명시할 필요 없이 만들어줄 수 있다
- 이런식으로 Field에 대한 default setting을
반응형
'웹개발 > Java' 카테고리의 다른 글
15 - 4. Java - Generic & 자료 구조 (0) | 2024.11.04 |
---|---|
15 - 3. Java - Static (0) | 2024.11.04 |
14 - 5. Java - Builder & 정적 팩토리 메서드 (1) | 2024.11.04 |
14 - 4. Java - Object 생성자 (0) | 2024.11.04 |
14 - 3. Java의 OOP 문법 - Encapsulation + Inheritence (0) | 2024.11.04 |