자바 - 메서드 참조
안녕하세요, 자바 프로그래머를 꿈꾸는 여러분! 오늘은 처음에는 조금 두려울 수 있는 주제이지만, 익숙해지면 정말 유용하다는 주제에 대해 깊이 들어가 볼 거예요. 우리는 자바의 메서드 참조에 대해 이야기할 거예요. 그럼, 좋아하는 음료를 준비하고 편하게 앉아서 함께 이 흥미로운 여정에 떠나보죠!
메서드 참조란 무엇인가요?
자세히 들어가기 전에 간단한 질문부터 해볼까요? 정확히 메서드 참조는 무엇인가요? 글쎄요, 쿠키를 잘 만드는 친구가 있다고 상상해봅시다. 매번 쿠키를 원할 때 루트를 전부 설명할 필요는 없죠. "쿠키를 만드는 거 하렴" 이렇게 말하면 돼요. 이것이 바로 자바에서의 메서드 참조란 거예요 – 메서드를 실행하지 않고 참조하는 간단한 방법이죠.
메서드 참조는 자바 8에서 람다 표현식 기능 일부로 도입되었습니다. 메서드나 생성자를 호출하지 않고 참조할 수 있는 방법을 제공합니다. "필요할 때 사용하렴" 이렇게 가리키는 것과 같아요.
자바 메서드 참조의 유형
이제 기본적인 이해를 가지셨으니, 다양한 유형의 메서드 참조를 탐험해봅시다. 네 가지 주요 유형이 있습니다:
- 정적 메서드 참조
- 특정 객체의 인스턴스 메서드 참조
- 특정 타입의 임의의 객체의 인스턴스 메서드 참조
- 생성자 참조
이제 각각을 자세히 살펴보고 코드 예제를 살펴보겠습니다.
1. 정적 메서드 참조
이것은 아마 가장 쉽게 이해할 수 있는 유형일 것입니다. 클래스의 정적 메서드를 참조하는 경우입니다. 예제를 보겠습니다:
import java.util.Arrays;
import java.util.List;
public class StaticMethodReference {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// 람다 표현식 사용
numbers.forEach(number -> System.out.println(number));
// 메서드 참조 사용
numbers.forEach(System.out::println);
}
}
이 예제에서 System.out::println
는 System.out
객체의 정적 println
메서드에 대한 메서드 참조입니다. 이는 number -> System.out.println(number)
람다 표현식과 동등하지만, 더 간결하고 가독성이 좋습니다.
2. 특정 객체의 인스턴스 메서드 참조
이 유형의 메서드 참조는 기존 객체의 인스턴스 메서드를 참조할 때 사용됩니다. 예제를 보겠습니다:
public class InstanceMethodReference {
public void printUpperCase(String s) {
System.out.println(s.toUpperCase());
}
public static void main(String[] args) {
InstanceMethodReference imr = new InstanceMethodReference();
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 람다 표현식 사용
names.forEach(name -> imr.printUpperCase(name));
// 메서드 참조 사용
names.forEach(imr::printUpperCase);
}
}
여기서 imr::printUpperCase
는 imr
객체의 printUpperCase
메서드에 대한 메서드 참조입니다. 이는 name -> imr.printUpperCase(name)
람다 표현식과 동등합니다.
3. 특정 타입의 임의의 객체의 인스턴스 메서드 참조
이 유형은 좀 더 복잡하지만, 따라오세요! 이 유형의 메서드 참조는 특정 타입의 임의의 객체의 메서드를 호출할 때 사용됩니다. 예제를 보겠습니다:
import java.util.Arrays;
import java.util.List;
public class ArbitraryObjectMethodReference {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 람다 표현식 사용
names.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
// 메서드 참조 사용
names.sort(String::compareToIgnoreCase);
}
}
이 예제에서 String::compareToIgnoreCase
는 String
클래스의 compareToIgnoreCase
메서드에 대한 메서드 참조입니다. 이는 (s1, s2) -> s1.compareToIgnoreCase(s2)
람다 표현식과 동등합니다.
4. 생성자 참조
마지막으로, 생성자에 대한 메서드 참조를 사용할 수도 있습니다. 이렇게 작동합니다:
import java.util.function.Supplier;
class Person {
private String name;
public Person() {
this.name = "Unknown";
}
public String getName() {
return name;
}
}
public class ConstructorMethodReference {
public static void main(String[] args) {
// 람다 표현식 사용
Supplier<Person> personSupplier1 = () -> new Person();
// 생성자 참조 사용
Supplier<Person> personSupplier2 = Person::new;
Person person1 = personSupplier1.get();
Person person2 = personSupplier2.get();
System.out.println(person1.getName()); // 출력: Unknown
System.out.println(person2.getName()); // 출력: Unknown
}
}
이 예제에서 Person::new
는 Person
클래스의 생성자에 대한 메서드 참조입니다. 이는 () -> new Person()
람다 표현식과 동등합니다.
메서드 참조를 사용하는 이유는 무엇인가요?
이제 "람다 표현식을 사용할 수 있을 테니 메서드 참조를 왜 사용해야 하지?"라고 궁금해할 수 있습니다. 좋은 질문입니다! 여기 몇 가지 이유가 있습니다:
- 가독성: 메서드 참조는 코드의 가독성과 간결성을 높입니다.
- 재사용성: 기존의 메서드 구현을 재사용할 수 있습니다.
- 성능: 일부 경우 메서드 참조가 람다 표현식보다 약간 더 효율적일 수 있습니다.
결론
그렇게 저희는 자바의 메서드 참조에 대한 기본을 다루었습니다. 기억해두세요, 새로운 개념을 배우는 것처럼, 메서드 참조에 익숙해지기 위해서는 연습이 필요합니다. 하지만 익숙해지면, 코드가 더 깔끔하고 표현력이 강화될 것입니다.
마무리하며, 제 가르침 경험에서的一则 이야기를 공유하고 싶습니다. 한 번은 메서드 참조에 어려움을 겪는 학생이 있었습니다. 그는 계속해서 "손가락 없이 뭘 가리키려고 하는 것 같아!"라고 말했어요. 하지만 연습을 좀 했더니 "이제 알겠다! TV를 매번 걸어가지 않고 리모컨을 사용하는 것 같아!"라고 외치며 깨달았어요. 바로 그런 거예요 – 메서드 참조는 메서드에 대한 작은 리모컨 같아요.
그럼, 계속 코딩하고 연습하며, 가장 중요한 것은 자바를 즐기세요! 기억해두세요, 모든 마스터는 처음엔初心자였습니다. 코딩하는 기쁨을 누리세요!
Credits: Image by storyset