2020-10-14 더자바 강의정리 스태틱 메서드

인터페이스 기본메서드, static 메서드

기본메서드

  • 인터페이스 메서드 선언이 아니라 구현체를 제공하는 방법
  • 해당 인터페이스를 구현한 클래스를 깨뜨리지 않고 새기능을 제공할 수 있다.
  • 기본 메서드는 구현체가 모르게 추가된 기능으로 리스크가 있다.
    • 컴파일 에러는 아니여도 구현체에 따라 런타임에러가 날 수 있다.
    • 반드시 문서화. @ImplSpec사용.
  • Object가 제공하는 기능(equals, hasCode)는 기본메서드로 제공할 수 없다. 구현체가 재정의 해야한다.
  • 인터페이스를 상속받는 인터페이스에서 다시 추상 메서드로 변경할 수 있다.
  • 인터페이스 구현체가 재정의 할 수 있다.
  • 우리가 수정할 수 있는 인터페이스에만 기본 메서드를 제공할 수 있다.
public class DefaultFoo implements Foo {
  private String name;
  public DefaultFoo(String name) {
    this.name = name;
  }
  @Override
  public void printName() {
    System.out.println(this.name);
  }
  @Override
  public String getName() {
    return this.name;
  }
  public static void main(String[] args) {
    Foo foo = new DefaultFoo("jimmy");
    foo.printName();
    foo.printNameUpperCase();
  }
}

public interface Foo {
  void printName();

  // @implSpec 이 구현체른 getName()으로 소문자->대문자로 바꿔서 출력
  default void printNameUpperCase() {
    System.out.println(getName().toUpperCase());
  }
  String getName();
}

public interface Bar extends Foo {
  void printNameUpperCase();
}
  • @implSpec을 통해 구현내용을 가르쳐주는게 필요.
  • Bar에서 Foo를 상속받고, 구현한 default메서드를 추상메서드로 다시 선언할 수 있다.
public class DefaultFoo implements Foo, Bar {
  private String name;
  ...
    public static void main(String[] args) {
    Foo foo = new DefaultFoo("jimmy");
    foo.printName();
    foo.printNameUpperCase();
    Foo.printAnything();

  }
}
public interface Foo {
  void printName();
  // @implSpec 이 구현체른 getName()으로 소문자->대문자로 바꿔서 출력
  default void printNameUpperCase() {
    System.out.println(getName().toUpperCase());
  }
  String getName();

  static void printAnything() {
    System.out.println("Foo static");
  }
}
public interface Bar {
  default void printNameUpperCase() {
    System.out.println("Bar upper " + getName().toUpperCase());
  }
  String getName();
}
  • DefaultFoo가 Foo, Bar인터페이스를 둘 다 구현하고, Foo, Bar에서 printNameUpperCase()를 default로 구현하면 컴파일에러가 난다.
  • static메서드를 정의해서 사용할 수도 있다.

스태틱 메서드

  • 해당 타입 관련 헬프 또는 유틸리티 메서드를 제공할 때 인터페이스에 스태틱 메서드를 제공할 수 있다.

자바8에 추가된 default메서드로 인한 API 변화

  • Iterable의 기본메서드

    • forEach()

      • public class Java8App {
          public static void main(String[] args) {
            List<String> name = new ArrayList<>();
            name.add("1");
            name.add("12");
            name.add("a");
            name.add("b");
            name.add("c");
            name.forEach(System.out::println);
          }
        }
        
    • spliterator() : iterator와 비슷한데 쪼갤 수 있는 기능이 있다.

      • public class Java8App {
          public static void main(String[] args) {
            List<String> name = new ArrayList<>();
            name.add("1");
            name.add("12");
            name.add("a");
            name.add("b");
            name.add("c");
        
            Spliterator<String> spliterator = name.spliterator();
            Spliterator<String> spliterator1 = spliterator.trySplit();
            while (spliterator.tryAdvance(System.out::println));
            System.out.println("================");
            while (spliterator1.tryAdvance(System.out::println));
          }
        }
        // result
        a
        b
        c
        ================
        1
        12
        
  • Collection의 기본메서드

    • stream() / parallelStream()

    • removeIf(Predicate)

      • public class Java8App {
          public static void main(String[] args) {
            List<String> name = new ArrayList<>();
            name.add("kee");
            name.add("whiteship");
            name.add("jimmy");
            name.add("toby");
            name.add("jay");
            name.removeIf(s -> s.startsWith("j"));
            name.forEach(System.out::println);
          }
        }
        // result
        kee
        whiteship
        toby
        
    • spliterator()

  • Comparator 기본메더드 및 스태틱 메서드

    • reversed()

      • public class Java8App {
          public static void main(String[] args) {
            List<String> name = new ArrayList<>();
            name.add("kee");
            name.add("whiteship");
            name.add("jimmy");
            name.add("toby");
            name.add("jay");
            Comparator<String> comparatorToIgnoreCase = String::compareToIgnoreCase;
            name.sort(comparatorToIgnoreCase.reversed());
            name.forEach(System.out::println);
          }
        }
        
    • thenComparing()

    • static reverseOrder() / naturalOrder()

    • static nullsFirst() / nullsLast()

    • static comparing()

Written on October 14, 2020