일단 Java에서 Lambda 는 표현식입니다. Lambda-Expression 입니다. 즉 Object 와 Class 처럼 메모리상에 올라가는 대상을 지칭하는 말이 아니라. int a = 0; 에서 0 처럼 값을 표현해주는 수단입니다. int a = 0 에서 0 은 a 의 초기화값을 표현해줍니다. 그리고 Lambda 는 FunctionalInterface(메소드가 하나뿐인 인터페이스) 에 해당하는 인터페이스의 Instance 값을 표현해줍니다. 메소드를 몇개 가지든, 클래스든 인터페이스든 추상클래스든 상관없이 상속하여 만들 수 있는 익명클래스와는 다릅니다.
구현도 다른데, 익명클래스의 경우 컴파일시 익명클래스의 Class 파일이 따로만들어 집니다. Class 파일을 보면, Main$1 과 같은 형식의 클래스 이름들이 있는데, 임시로 만들어진 익명클래스 이름입니다. 그러나, Labmda-Expression 는 그러한 클래스파일을 만들지 않습니다. 추가로 람다는 익명메소드로 저장된다는 글이 있습니다.(출처) 또한 메소드레퍼런스가 람다와 같은 기술을 사용하는 것으로 볼때, 옳다고 여겨지긴 합니다.(확인 바랍니다)
아래 예시는 익명 클래스와 Lambda 와 익명클래스의 차이점을 보여주는 테스트 코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public class Main { public static void main(String[] args) { Main main = new Main(); } public Main(){ getMyFunctionalInterfaceParameter((arg1, arg2) -> {}); getMyFunctionalInterfaceParameter(MyOjbect::staticMethod); getMyFunctionalInterfaceParameter(new MyOjbect()::methodA); getMyObjectParameter(new MyOjbect(){ @Override public void methodA(Object arg1, Object arg2) { super.methodA(arg1, arg2); } @Override public void methodB() { super.methodB(); } }); } public static void getMyFunctionalInterfaceParameter(MyFunctionalInterface functionalInterface){ System.out.println(functionalInterface.getClass().getName()); } public static void getMyObjectParameter(MyOjbect myOjbect) { System.out.println(myOjbect.getClass().getName()); } public interface MyFunctionalInterface{ void operator(Object arg1, Object arg2); } public static class MyOjbect{ public static void staticMethod(Object arg1, Object arg2){ } public void methodA(Object arg1, Object arg2){ } public void methodB(){ } } } |
결과:
com.company.Main$$Lambda$14/0x0000000800066040
com.company.Main$$Lambda$15/0x0000000800065840
com.company.Main$$Lambda$16/0x0000000800098040
com.company.Main$1
com.company.Main$$Lambda$15/0x0000000800065840
com.company.Main$$Lambda$16/0x0000000800098040
com.company.Main$1