Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

4 Weeks - [인터페이스에서 정적 메서드와 디폴트 메서드] #68

Open
leetaggg opened this issue Sep 3, 2023 · 1 comment
Assignees

Comments

@leetaggg
Copy link
Member

leetaggg commented Sep 3, 2023

문제

인터페이스에서 정적 메서드와 디폴트 메서드의 필요성과 해당 메서드들이 포함된 인터페이스를 구현, 상속 시 차이점이 궁금합니다!

contents - 세부 내용

둘의 필요성과 차이점이 헷갈리기도 하고, 다들 다시 한번 알아보면 좋을 것 같아 질문해 봤습니다.

참고

p.412

@dpwns523 dpwns523 self-assigned this Sep 5, 2023
@dpwns523
Copy link
Collaborator

dpwns523 commented Sep 8, 2023

책에서 언급된 내용은 다음과 같습니다

  • 자바 8이전의 자바는 인터페이스 그리고 인터페이스를 활용할 수 있는 다양한 정적 메서드를 정의하는 유틸리티 클래스를 활용
  • 자바 8에서는 인터페이스에 직접 정적 메서드를 선언할 수 있으므로 유틸리티 클래스를 없애고 직접 인터페이스 내부에 정적 메서드를 구현할 수 있음
  • 과거 버전과의 호환성을 유지할 수 있도록 자바 API에는 유틸리티 클래스가 남아있다

첫 번째로 헷갈릴 수 있었던 요소 중 하나가 java.util.Collectionjava.util.Collections의 차이가 무엇인가?라면

  • 자바 8이전의 인터페이스에서 제공할 수 없었던 정적 메서드를 제공하는 유틸클래스라는 것과 하위 버전 호환성때문에 Collection이라는 인터페이스와 Collections라는 유틸클래스가 같이 존재한다는 것을 이해할 수 있습니다

그렇다면 정적 메서드를 따로 나눠서 유틸클래스로 활용하는 방법은 공통된 기능을 재사용하기 좋다고 생각하는데 왜 인터페이스에 정적 메서드를 제공할 수 있도록 변경되었는가?

(A static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.) This makes it easier for you to organize helper methods in your libraries;

oracle java 문서에 의하면 인터페이스에 정적 메서드를 사용할 수 있도록 추가한 것은 별도의 클래스가 아닌 동일한인터페이스에서 특정한 정적 메서드를 유지하여 쉽게 구성할 수 있도록 하기 위함이라고 말하고 있습니다


인터페이스에 특정한 정적 메서드를 구현하면 얻어올 수 있는 장점

  • 하나의 인터페이스에서 원하는 기능을 추가하고 사용할 수 있다
    • 유연한 확장이 가능하다
  • 정적 메서드라는 것은 인스턴스를 생성하지 않고 호출할 수 있다는 것
    • Collections에서 list를 만드는 것과 List 인터페이스에서 of를 호출해서 만드는 것의 직관성, 가독성이 올라간다

인터페이스에 정적 메서드를 제공할 수 있게 바뀐것과 유사하게 디폴트 메서드를 제공할 수 있다는 것은 유사한 장단점이 있습니다

장점

  • 새로운 메서드를 기존 인터페이스에 추가할 수 있으며 기존 클래스에 구현하지 않아도 됨
  • 디폴트 메서드는 인터페이스를 구현한 클래스에서 재사용할 수 있음
  • 구현체에 따라 오버라이드하여 사용할 수 있음

단점

  • 다이아몬드 문제
    • 여러 인터페이스에서 동일한 디폴트 메서드를 상속할 때 발생하는 문제로 어떤 메서드를 호출해야할 지 모호해짐
  • 다양한 디폴트 메서드를 유지보수하는 비용
  • 모든 구현체에 같은 디폴트 메서드가 상속되어 필요 없는 구현체는 오버헤드가 발생

위의 내용들로는 아직 디폴트 메서드를 사용하나, 정적 메서드를 사용하나 큰 차이가 없어보이며, 정적 메서드가 오히려 구현체를 만들지 않고, 인스턴스 생성도 필요 없이 호출할 수 있어 더 좋아보일 수 있습니다

이 부분에 대해 디폴트 메서드와 정적 메서드를 비교하려면
객체지향적 관점과 메모리 관점에서 알아볼 필요가 있을 것 같습니다


객체지향적 관점

  • 객체지향은 객체의 상태를 기반으로 동작을 하는 특성을 가지는 패러다임
    • 정적 메서드는 공통의 기능을 제공하므로 객체의 상태와 무관하게 동일한 동작을 함
  • 다형성
    • 정적 메서드는 객체의 동작을 확장하거나 변경할 수 있는 다형성을 제공하지 못함

위의 특성을 통해 정적 메서드는 사용하는 클래스가 한정적이며 이는 결합도가 높아지는 것을 생각해볼 수 있다
반면에 디폴트 메서드는 모든 부분에서 객체지향 패러다임을 깨지 않고 사용할 수 있음


메모리 관점?

image
오라클에서 제공되는 JVM Architecture입니다 이번에 관심있게 살펴볼 부분은 Method Area와 Heap입니다

  • 정적 메서드는 Method Area에 할당 되며 디폴트 메서드가 있는 인터페이스는 구현체 인스턴스를 생성할 때 Heap영역에 할당됩니다
  • Heap영역은 GC의 관리를 받지만, Method Area에 할당되며 GC에 관리를 받지 않고 프로그램 종료 시 까지 정보를 가지고 있습니다

자바 8이전에는 Method Area와 Heap 메모리 영역이 모두 JVM이 관리했기 때문에 Method Area의 메모리크기가 GC에 영향을 줬다 자바 8이후로 Method Area는 JVM이 아닌 OS의 관리 영역으로 하여 GC의 효율을 높였다고 하며 정적 변수에 의해 GC에 영향을 끼치지 않는다고 한다

따라서 메모리적 관점에서 성능을 논하지는 않는다는 것 입니다


JVM을 살펴봤으니 메서드 호출 시 차이점

정적 메소드가 인터페이스 구현체의 메서드를 호출하는 것 보다 속도가 빠릅니다 (하지만 거의 무시해도 될 만큼 적은 차이)

그 이유는 정적 메서드는 프로그램 실행 시점에 이미 컴파일된 바이트 코드를 저장하고 있음
인터페이스 구현체의 메서드는 호출 시 클래스 로더가 동적으로 구현체를 찾아 바이트코드를 로딩해오기 때문에 시간이 조금 더 걸림


결론적으로

디폴트 메서드와 정적 메서드는 인터페이스 내에서 둘 다 사용되고 있으며
정적 메서드는 객체지향적 패러다임을 깰 수 있는 요소가 많기에 사용을 지양하고
객체의 상태의 따라 동작이 결정되지 않는 유틸리티 메서드만 제공해야한다는 것입니다

유틸리티 메서드? ex: 정적 팩토리 메서드

Reference

JVM Architecture
Static Methods
객체지향적 관점에서 static

@devjy39 devjy39 closed this as completed Sep 8, 2023
@devjy39 devjy39 reopened this Dec 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants