본문으로 바로가기

[java] 자바 8 메소드 레퍼런스 (Method Reference)

category Backend/Java 2021. 12. 15. 01:10

목차

    1. 메소드 레퍼런스

    • 메소드 레퍼런스는 람다 표현식을 구현할 때 쓸 수 있는 방법으로 기존에 있던 다른 메소드를 참조하여 그 메소드 자체를 함수형 인터페이스의 구현체로 사용합니다.
    • 람다의 구현 자리를 기존에 이미 있는 어떤 메서드를 참조하는 방식
    • 람다 표현식이 단 하나의 메소드만을 호출하는 경우에 해당 람다 표현식에서 불 필요한 매개변수를 제거하고 사용할 수 있습니다.
    • :: 연산자를 이용해 메소드 이름과 클래스를 분리하거나, 메소드 이름과 객체의 이름을 분리합니다.
      • 클래스::메소드
      • 객체::메소드
      • 클래스::new

    [간단한 예시]

    • 람다표현식과 해당 람다표현식을 메소드 레퍼런스를 이용해 작성하였습니다.
    • 위에서 설명한 것 처럼 함수형 인터페이스와 메소드 레퍼런스를 이용하여 람다 표현식에서 불 필요한 매개변수를 제거하고 작성 할 수 있습니다.
    • 메소드 자체를 함수형 인터페이스의 구현체로 사용합니다.
    import java.util.function.*;
    
    public class Exe {
    
        public static void main(String args[]) {
    
            // 받은 값 출력
            Consumer<String> printName1 = name -> System.out.println(name);
            Consumer<String> printName2 = System.out::println;
    
            // 문자열 수 반환
            Function<String, Integer> lengthStr1 = string -> string.length();
            Function<String, Integer> lengthStr2 = String::length;
    
            // 문자열 비교
            BiFunction<String, String, Boolean> equalCheck1 = (str1, str2) -> str1.equals(str2);
            BiFunction<String, String, Boolean> equalCheck2 = Object::equals;
    
            // 숫자 비교(큰 수 반환)
            BinaryOperator<Integer> maxNum1 = (num1, num2) -> Math.max(num1, num2);
            BinaryOperator<Integer> maxNum2 = Math::max;
    
        }
    }

    2. 메소드 레퍼런스 패턴

    메소드 레퍼런스에는 3가지 유형이 있습니다.

    1. 스태틱 메소드 참조 (Static Method Reference) → 클래스::정적메소드 (static)
    2. 특정 객체의 인스턴스 메소드 참조 (Instance Method Reference) → 객체::인스턴스메소드 (public)
    3. 생성자 참조 (Constructor Method Reference) → 클래스::new

    예시를 위해 자바 8 표준 함수형 인터페이스(java.util.function)를 활용하였습니다. 잘 모르겠다면 아래의 링크를 참조해주세요.

    https://veneas.tistory.com/entry/java-자바-8-표준-함수형-인터페이스-javautilfunction

    2.0. 테스트용 클래스

    public class User {
    
        private String name;
        private String bloodType;
    
        //==User 기본 생성자==//
        public User() {
    
        }
    
        //==User 생성자==//
        public User(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public String getBloodType() {
            return bloodType;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setBloodType(String bloodType) {
            this.bloodType = bloodType;
        }
    
        //==User객체 생성 메서드(static)==//
        public static User createUser(String name, String bloodType) {
            User user = new User();
            user.setName(name);
            user.setBloodType(bloodType);
            return user;
        }
    }

    2.1. Static Method Reference

    import java.util.function.*;
    
    public class Exe {
    
        public static void main(String args[]) {
    
            // 스태틱 메소드 참조하여 객체 생성
            BiFunction<String, Integer, SoccerPlayer> createUserMethodRefer = SoccerPlayer::createPlayer;
            SoccerPlayer player2 = createUserLambda.apply("Haaland", 194);
        }
    }

    2.2. Instance Method Reference

    import java.util.function.*;
    
    public class Exe {
    
        public static void main(String args[]) {
    
            // 스태틱 메소드 참조하여 객체 생성
            BiFunction<String, Integer, SoccerPlayer> createUserMethodRefer = SoccerPlayer::createPlayer;
            SoccerPlayer son = createUserMethodRefer.apply("Son Heung-min", 183);
    
            // 특정 객체의 인스턴스 메소드 참조하여 이름과 키 값 반환
            Supplier<String> name = son::getName;
            Supplier<Integer> height = son::getHeight;
            
            System.out.println(name.get()); // Son Heung-min
            System.out.println(height.get()); // 183
        }
    }

    2.3. Constructor Method Reference

    import java.util.function.*;
    
    public class Exe {
    
        public static void main(String args[]) {
    
            // 생성자 참조하여 기본 생성자로 객체 생성
            Supplier<SoccerPlayer> soccerPlayer1 = SoccerPlayer::new;
            SoccerPlayer player1 = soccerPlayer1.get(); // get을 해야 생성자를 이용해 객체 생성 됩니다.
    
            // 생성자 참조하여 생성자로 객체 생성
            Function<String, SoccerPlayer> soccerPlayer2 = SoccerPlayer::new;
            SoccerPlayer player2 = soccerPlayer2.apply("Lee Kang-in");
        }
    }