본문 바로가기
Java/The Java

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

by 어썸오184 2021. 7. 29.
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
반응형

댓글