JaPark Bug World

Item1. 생성자 대신 정적 팩터리 메서드를 고려하라. 본문

개발새발/Effective Java

Item1. 생성자 대신 정적 팩터리 메서드를 고려하라.

JAstory 2024. 3. 26. 11:50

* 해당 내용은 인프런 이펙티브 자바 완벽 공략 1부 백기선님의 영상을 기준으로 작성하였습니다. https://inf.run/fnnRy

 

백기선 이펙티브 자바 완벽 공략 1부 강의 - 인프런

자바 학습의 끝판왕 “이펙티브 자바”를 보다 쉽고 완벽하게 학습하세요. 이 강의를 수강하시면 여러분의 자바 프로그래밍 지식과 실력뿐 아니라 학습 능력 또한 향상 시킬 수 있습니다., MS 시

www.inflearn.com

 

1. 열거타입 (Enumeration)

  • 상수 목록을 담을 수 있는 데이터 타입
  • 특정한 변수가 가질 수 있는 값을 제한할 수 있다. 타입-세이프티(Type-Safety)를 보장 할 수 있다.
  • 싱글톤 패턴을 구현할 때 사용하기도 한다.
  • 질문1) 특정 enum 타입이 가질 수 있는 모든 값을 순회하며 출력하라
    • Arrays.strem(EnumClassName.values()).forEach(System.out::println);
  • 질문2) enum은 자바의 클래스처럼 생성자, 메소드, 필드를 가질 수 있는가?
    • 해당 질문에 답이 떠오르지 않다면.. 기초책을 다시 봐야 한다고 했다..
    • 가능하다.
  • 질문3) enum의 값은 == 연산자로 동일성을 비교할 수 있는가?
    • 오로지 하나의 인스턴스만 가지고 있음을 보장하기 때문에 가능하다. 
    • == 을 쓰는것을 권장
  • 과제) enum을 key로 사용하는 Map을 정의하세요. 또는 enum을 담고 있는 Set을 만들어 보세요.
    • EnumMap or EnumSet을 써서 가능. 
    • 왜 이것을 사용하면 좋은지 이유를 알아야한다.

2. 플라이웨이트 패턴 (Flyweight pattern) 

같은 객체가 자주 요청되는 상황이라면 사용할 수 있다.

  • 객체를 가볍게 만들어 메모리 사용을 줄이는 패턴
  • 자주 변하는 속성과 변하지 않는 속성을 분리하고 재사용하여 메모리 사용을 줄일 수 있다.

3. 인터페이스에 정적 메소드

  • 기본 메소드와 정적 메소드를 가질 수 있다.
  • 기본 메소드
    • 인터페이스에서 메소드 선언 뿐 아니라, 기본적인 구현체까지 제공할 수 있다.
    • 기본 접근제한자는 public이라 따로 명시가필요 없다.
    • 기존의 인터페이스를 구현하는 클래스에 새로운 기능을 추가할 수 있다
  • 정적 메소드
    • 자바 9부터 private static 메소드도 가질 수 있다.
    • 단, private 필드는 아직도 선언할 수 없다.
public interface HelloBye {
	String hello();
	
	// instance type method 
	default String hi() {
		return "hi";
	}
	
	// static type method
	static String bye() {
		return "bye";
	}
}

 

  • 질문1) 내림차순으로 정렬하는 Comparator를 만들고 List<Integer>를 정렬하라.
public class ArrayTest {
	public static void main(String[] args) {
		List<Integer> arrs = Arrays.asList(1,2,3,4,5);
		Comparator<Integer> desc = (o1, o2) -> o2 - o1;
		arrs.sort(desc);
		System.out.println(arrs);
	}
}
  • 질문2) 질문1에서 만든 Comparator를 사용해서 오름차순으로 정렬하라.
public class ArrayTest {
	public static void main(String[] args) {
		List<Integer> arrs = Arrays.asList(1,2,3,4,5);
		Comparator<Integer> desc = (o1, o2) -> o2 - o1;
		arrs.sort(desc.reversed());
		System.out.println(arrs);
	}
}

 

4. 서비스 제공자 프레임워크 - 확장 가능한 애플리케이션을 만드는 방법

5. 리플렉션(reflection)

  • 클래스로더를 통해 읽어온 클래스 정보를 사용하는 기술
  • 리플렉션을 사용해 클래스를 읽어오거나, 인스턴스를 만들거나, 메소드를 실행하거나, 필드의 값을 가져오거나 변경하는 것이 가능하다.
  • 언제 사용할까?
    • 특정 애노테이이션이 붙어있는 필드 또는 메소드 읽어오기(JUnit, Spring)
    • 특정 이름 패턴에 해당하는 메소드 목록 가져와 호출하기(getter, setter)
  • https://docs.oracle.com/javase/tutorial/reflect/