Java/The Java

[Java] 메서드 시그니처 vs 메서드 타입

어썸오184 2021. 7. 29. 17:19
728x90
반응형

더블 디스패치에 대해 공부하려고 토비님의 유튜브 영상을 보다가 메서드 시그니처(method signature)와 메서드 타입(method type)에 대해 정리해주시는 것을 보고 정리해둘 필요가 있을 것 같아 포스팅해봅니다.

메서드 시그니처(Method Signature)

시그니처, 말 그대로 서로다른 메서드를 구분하는 근거가 되는 요소입니다. 메서드 오버라이딩을 할 때 중요합니다.

메서드 시그니처의 구성 요소

  • 메서드 이름
  • 파라미터 리스트

이 두 가지가 같으면 메서드를 오버라이딩할 수 있으며, 이 두 가지가 같은 메서드가 한 클래스 내에 두 개 이상 정의되어 있으면 메서드 중복으로 컴파일 에러가 발생합니다.

여기서 파라미터 리스트라는 것은 파라미터의 타입, 개수, 순서를 말합니다. 예를 들어 파라미터의 타입과 개수가 같더라도 순서가 다르면 다른 메서드로 인식됩니다.

public class Demo {

    public String methodA(int intA, String stringA) {
        return "int string";
    }

    public String methodA(String stringA, int intA) {
        return "string int";
    }

    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.methodA(1, "");
        demo.methodA("", 1);
    }
}

❗️주의! 메서드의 리턴 타입은 메서드 시그니처가 아니다. 즉 메서드 이름과 파라미터 타입이 같고 리턴 타입만 다르면 컴파일 에러가 발생한다.

추가적으로 상속을 할 때는 반환타입이 같아야하는데, 오버라이딩 하는 쪽의 리턴 타입이 Covariant하면 타입이 달라도 됩니다.

public class Parent {

    Parent hello(int a) {
        return null;
    }
}

class Child extends Parent {

    @Override
    Child hello(int a) {
        return null;
    }
}

 

메서드 타입(Method Type)

메서드 타입은 Java8의 메서드 레퍼런스를 사용할 때 중요한 개념. 메서드 타입이 같으면 메서드 레퍼런스를 사용할 수 있다.

메서드 타입 구성 요소

  • 리턴 타입
  • 타입 파라미터
  • 아규먼트 타입
  • 예외

근데 토비님 말씀을 듣고 실험을 해봤는데 리턴 타입이 달라도 메서드 레퍼런스가 잘 동작해서 의문이 든다;;

예를 들어, List의 forEach 메서드는 매개변수로 Consumer를 받는데, Consumer는 인자가 하나고 반환타입이 void인 함수형 인터페이스이다. 그런데 아래와 같이 리턴 타입이 있는 메서드를 전달해도 잘 동작하는 것을 볼 수 있다.

import java.util.Arrays;
import java.util.List;

public class Demo {

    public static void main(String[] args) {
        List<Integer> arr = Arrays.asList(1, 2, 3, 4, 5);
        arr.forEach(Foo::print);
    }
}

class Foo {
    public static int print(int a) {
        System.out.println(a);
        return a;
    }
}

그래서 Method Type이라는게 정확히 뭔지 알아보려고 자료를 찾아봐도 잘 나오지 않아서 정확히 확인을 못하겠다.

내가 예시를 잘못 사용한건지, 설명을 제대로 이해 못한건지,, 아시는 분 있으면 댓글 달아주시면 감사하겠습니다.

728x90
반응형