작성
·
150
0
강의 수강 중 궁금하여 실험한 내용 공유합니다. 2번 특정 객체의 인스턴스 참조에 관련한 내용입니다.
강의자료에서는 () -> person.introduce
가 person::introduce
와 동일한 것처럼 설명된 것 같습니다. "그럼 person
에 대한 캡처가 일어날까?" 하는 궁금증이 들었고, 다음과 같은 코드를 작성했습니다.
Person person = new Person("Kim");
Supplier<String> instanceMethod = () -> person.introduce();
person = new Person("Lee");
System.out.println(instanceMethod1.get());
컴파일러가 person
이 사실상 final이 아니라면서 컴파일해주지 않더군요. 다음으로는 람다 대신 메소드 참조로 바꾸어보았습니다.
Person person = new Person("Kim");
Supplier<String> instanceMethod = person::introduce;
person = new Person("Lee");
System.out.println(instanceMethod.get());
이는 컴파일에 성공하고, "I am Kim"이 출력됩니다.
Person
클래스에 setName
을 추가하고 메소드 참조 이후에 호출해보았습니다.
Person person = new Person("Kim");
Supplier<String> instanceMethod = person::introduce;
person.setName("Park");
person = new Person("Lee");
System.out.println(instanceMethod.get());
"I am Park"이 출력됩니다.
요약하면 다음과 같습니다.
() -> person.introduce
에서는 person
이 사실상 final이 되어야만 한다.
person::introduce
는 사실상 final이 아니어도 되며, 해당 메소드 참조는 정의 시 객체 참조를 유지한다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. 한재현님.
인스턴스 메소드 참조와 람다 표현식의 차이에 대해 실험을 통해 알아보신 점 잘 정리해주셨네요! 공유해주신 결과는 람다와 메소드 참조의 특성을 이해하는 데 큰 도움이 됩니다.
설명: 람다 식인 () -> person.introduce()
는 람다 내부에서 사용되는 변수 person
이 사실상 final
이어야 합니다. 이는 람다에서 외부 변수의 값을 캡쳐할 때 변경되지 않도록 보장하기 때문입니다. 반면, 메소드 참조인 person::introduce
는 변수 person
이 더 이상 바뀔 수 있습니다. 이 경우, 메소드 참조는 정의 시점의 person
객체를 참조하여, 이후 해당 객체의 상태 변화를 반영하게 됩니다.
결과 실험:
1. person = new Person("Lee");
코드에서 람다 식이 컴파일되지 않는 이유는 person
이 사실상 final
이 아니기 때문입니다. 그러나 메소드 참조는 정의된 객체 상태를 유지하도록 합니다.
2. person.setName("Park");
다음 출력이 “I am Park”인 이유는, 메소드 참조가 정의 당시의 객체 person
을 가리키고 있고, 그 객체의 상태가 변화되었기 때문입니다.
이 차이점은 자바 프로그래밍에서 상태관리를 이해할 때 많이 활용됩니다. 메소드 참조가 더 유연하게 사용될 수 있는 상황을 이해하는 데도 도움이 됩니다.
추가적으로 아래의 링크에서 관련 내용을 확인해 보실 수 있습니다:
- 인스턴스 메소드 참조와 람다 식의 차이점 관련 질문들
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.