자바의 람다는 익명클래스와 매우 비슷한 모습을 하고있다.
그러나 둘은 아주 다르다.
익명클래스
일단 익명클래스는 어쨌거나 사용할 때 보통 객체와 동일하게 힙에 할당이 된다.
메인메소드 내에서 익명클래스를 사용하면 컴파일 시에 $1, $2 등과 같은 순서대로
클래스파일이 생성이 된다.
예시로, 평범한 인터페이스를 하나 선언한다.
추상클래스나 일반 클래스도 상관없다.
interface Test{
public int getNum();
}
그 후, 메인에서 바로 사용하기 위해 재정의를 해준다.
public class LambdaTest {
public static void main(String[] args) {
Test t1 = new Test(){
public int num = 10;
public int getNum(){ return this.num; }
};
System.out.println(t1.getNum());
}
}
이렇게 하면 메인함수에서 바로 구현체를 만들어 사용할 수 있다는 특징이 있다.
이것이 익명 클래스의 기본이다.
또한 익명클래스 사용 시 위 사진처럼 $1 클래스 파일이 만들어진다.
그리고 클래스이므로 객체를 계속 생성하여 사용하여야한다. ( 메모리에 계속 증가 )
람다는 그러면 무슨 차이점이 있는가?
일단, 자바 객체 생성 후 메소드를 찍어보면 클래스명.메소드() 호출 하는것을 볼 수 있을것이다.
객체명.메소드()가 아니라 클래스명.메소드().. 이것은 어떻게 된 일이냐면
자바 Permanent 영역에 메소드를 저장해놓는데,
이 메소드는 한번 저장해놓고 객체들이 이 주소지로 넘어오는 것이다.
한번 만들어놓고 계속 참조하는것이다.
그러면 이게 람다와 무슨 상관이 있는가?
람다는 식 그 자체이다.
익명클래스처럼 구현을 하는 것 같아도 위에 말한 메소드처럼 굴러간다는 것이다.
즉, 이 주소로 바로 Branch하게 된다는 것이다.
익명클래스처럼 객체를 생성하지않고 바로 메소드의 주소로 이동한다고 보면 된다.
무엇보다 코드의 길이를 확 줄일수 있다는 장점도 있고, 가독성이 떨어진다는 단점도 가지고 있지만
여러모로 유용하다는 장점이 있다.
최근 트렌드는 함수형 프로그래밍이므로 잘 알아두는 것이 좋다.
람다에 대한 예시를 들자면
Comparator<Point> comparator = (Point p1, Point p2) -> {
if (p1.x > p2.x) {
return 1;
}else if(p1.x < p2.x){
return -1;
}else{
return 0;
}
};
Collections.sort(pointList, comparator);
첫번째 방법으로는 사용 전에 미리 식을 정의 해두는 것이 있고.
Collections.sort(pointList, (Point p1, Point p2) -> {
if (p1.x > p2.x) {
return 1; // x에 대해서는 오름차순
}else if(p1.x < p2.x){
return -1;
}
return 0;
})
두번째 방법으로는 사용 할 때 매개변수를 재정의해버리는 것이 있다.
사용방법은 예시는 위와 같고, 사용법은 아래와 같다.
인터페이스 인터페이스 명 = (매개변수 자료형 매개변수이름) -> { 메소드 본체 }
사용 시 참고 사항
1. 인터페이스 내의 메소드가 하나만 존재하여야한다. (default와 static메소드는 상관이 없다.)
2. 여러개를 생략할 수 있다, 매개변수의 괄호 그리고 자료형, 메소드의 몸체가 되는 부분의 괄호
3. return 생략시 ;(semi colon)도 생략하여야한다.
4. new가 애초에 생략되어 있을 뿐이다. 기본 골자는 익명클래스와 비슷하긴 하다.
API 문서에서 @FunctionalInterface 라고 표시 해놓은것에선 무조건 된다.
물론 우리도 사용하기 위해선 인터페이스에 어노테이션으로 적어두어야한다.
나머지는 다음 글에서 자세히 설명하도록 하겠다.
'Java' 카테고리의 다른 글
로그백 실행방법(logback, java) (0) | 2019.11.07 |
---|---|
자바 콘솔에서의 다양한 실행방법(jar, 빌드) (0) | 2019.11.07 |
JAVA Exception 예외, 사용자 정의 예외처리 만드는법 (0) | 2019.08.05 |
Comparable, Comparator를 이용한 객체간 크기 비교 (0) | 2019.07.30 |
Reflection 이란 ? JAVA Reflection, Reflect Class, RTTI (0) | 2019.07.30 |