람다 표현식은 java8 이후에 업데이트되며, 는 기능 인터페이스의 익명 내부 클래스 구현을 단순화하는 데 사용됩니다.. 소위 기능적 인터페이스는 인터페이스에 하나의 추상 메소드만 있음을 의미합니다(인터페이스에는 기본 메소드, 개인 메소드 및 클래스 메소드도 있을 수 있지만 추상 메서드는 하나만 있을 수 있습니다.)
동작을 메서드에 매개 변수로 전달해야 하는 경우 메서드 매개 변수를 기능적 인터페이스 유형으로 작성한 다음 Lambda 표현식을 사용하여 구현 클래스 객체를 생성하고 이를 실제 매개 변수로 메서드에 전달할 수 있습니다.
람다 표현식의 핵심 목적은 코드를 단순화하는 것입니다. 단순화의 부작용은 직관적이지 않다는 점이지만 생략 방법을 익히면 코드가 다음과 같이 보일 것입니다. 매우 우아합니다.
람다 표현식 구문
일반 구문 형식은:
(매개변수 목록) -> {메소드 본문의 문}입니다.
함수형 인터페이스의 구현 클래스 객체를 생성할 때 람다 표현식을 사용하기 때문에 호출되는 메소드의 형식적 매개변수에 따라 인터페이스의 타입이 결정되므로 직접 생략할 수 있다.
그리고 기능적 인터페이스에는 추상 메소드가 하나만 있으므로 추상 메소드만 다시 작성하면 됩니다 . 재정의된 추상 메서드의 경우 메서드 이름이 고정되어 인터페이스 정의에서 확인할 수 있으며 직접 생략할 수 있습니다. 따라서 메소드의 매개변수 목록을 작성한 다음 구현 클래스에 의해 대체된 메소드 본문 부분을 추가하기만 하면 기능 인터페이스의 구현 클래스 정의를 완료할 수 있습니다.
그러면 일반 구문의 왼쪽이 매개변수 목록 부분으로 추상 메소드 메소드 헤더의 유효 정보에 해당하고 오른쪽이 실행문임을 알 수 있습니다. 추상 메소드 메소드 바디의 핵심 정보에 해당하는 메소드 바디. 따라서 위의 구문 형식은 이상하게 보일 수 있지만 실제로는 충분히 단순화된 결과입니다.
익명의 내부 클래스와 해당 Lambda 표현식을 예로 사용:
@FunctionalInterface
interface InterA {
int add(int a, int b);
}
public class LambdaDemo1 {
public static void main(String[] args) {
// 这里传入匿名内部类创建的对象
userInterA(new InterA() {
@Override
public int add(int a, int b) {
return a + b;
}
});
// 省略后的对应Lambda表达式,左边是抽象方法的形参列表,右边是重写的方法体
// 参照上面,可以完全找到对应关系,但下面的代码明显更简洁
userInterA((int a, int b) -> {
return a + b;});
}
public static void userInterA(InterA a) {
int num = a.add(6, 5);
System.out.println(num);
}
}
람다 표현 생략
더욱 단순화하기 위해 람다 표현식을 더욱 단순화할 수 있습니다. 단순화를 위한 규칙은 다음과 같습니다.
- 정식 매개변수 목록 중 형식 매개변수 유형은 생략 가능.
사실 인터페이스 정의 부분에서 형식적 매개변수 유형이 고정되어 있어 다시 작성할 필요가 없기 때문에 이해하기 쉽습니다. - 형식 매개변수에 매개변수가 하나만 있는 경우 괄호는 생략할 수 있습니다.
- 메서드 본문에 한 줄의 명령문만 있는 경우, 중괄호를 생략할 수 있습니다 a>,문 끝의 세미콜론도 제거해야 합니다. 유일한 문 이 return 문인 경우 , 는 return 키워드를 생략해야 합니다 , 시스템은 메서드가 값을 반환해야 함을 감지하고 표현식의 결과를 반환 값으로 직접 반환합니다.
메소드 참조 및 생성자 참조
추상 메서드로 재정의되는 람다 표현식의 메서드 본문이 한 줄만 있고 다음 조건을 만족한다면, 이를 더욱 축약하여 다음과 같은 상황으로 나눌 수 있다.
1. 참조 클래스 메소드
람다 표현식의 형식이 다음과 같은 경우: (a,b,…) -> 클래스 이름.클래스 메소드 (a,b,…)
형식 매개변수 목록의 모든 매개변수는 참조 클래스 메소드의 해당 매개변수로 사용됩니다. 경우 다음과 같이 축약할 수 있습니다. :클래스 이름::클래스 메서드
-
특정 객체의 인스턴스 메소드 참조
람다 표현식의 형식이 (a,b,…)인 경우 -> 특정 객체 이름.인스턴스 메소드(a ,b,…) )
형식 매개변수 목록의 모든 매개변수는 특정 객체를 참조하는 인스턴스 메소드의 해당 매개변수로 사용됩니다.< /span>특정 개체 이름::인스턴스 메서드 다음과 같이 축약할 수 있습니다: -
객체의 인스턴스 메소드 참조
람다 표현식의 형식이 다음과 같은 경우: (a,b,c,…) -> a.인스턴스 메소드 (b,c , …)
매개변수 목록의 첫 번째 매개변수가 호출자로 사용되고 나머지 매개변수는 모두 오른쪽의 해당 매개변수로 사용됩니다. , 다음과 같이 축약될 수 있습니다: 클래스 이름::인스턴스 메소드, 여기서 클래스 이름은 다음 유형입니다. 첫 번째 매개변수. -
참조 생성자
람다 표현식의 형식이 다음과 같은 경우: (a,b,…) -> 새 클래스 이름 (a,b,…)< a i=2> 매개변수 목록의 모든 매개변수는 호출된 생성자의 해당 매개변수로 사용됩니다. 이 경우 다음과 같이 축약될 수 있습니다. < a i=5>클래스 이름::new
람다 표현식의 일반적인 사용 시나리오
세 가지 유형으로 나뉩니다.
- 기능적 인터페이스 유형에 할당된 참조 변수
- 기능적 인터페이스 유형의 매개변수로 메소드에 전달됩니다.
- 기능적 인터페이스를 사용하여 람다 표현식 캐스팅
람다 표현식의 유형은 고정되어 있지 않고 어떤 기능 인터페이스가 구현되는지에 따라 전적으로 달라집니다. 따라서 람다 표현식으로 생성되는 구현 클래스 객체는 사용 시나리오에 따라 변경됩니다. .
람다 표현식 및 익명 내부 클래스
람다 표현식의 핵심은 Functional Interface에 해당하는 Anonymous Inner Class의 약자입니다.Anonymous Inner Class가 Functional Interface를 구현하는 경우에는 다음과 같이 대체할 수 있습니다. 람다 표현식.
그러나 람다 표현식은 추상 메서드만 재정의할 수 있고 새 메서드를 추가할 수는 없습니다.
그리고 람다 표현식으로 생성된 객체는 인터페이스의 기본 메소드를 상속받을 수 있지만 인터페이스의 기본 메소드는 람다 표현식에서 호출할 수 없습니다< /span> .
그러나 익명 내부 클래스가 수행할 수 있는 많은 작업은 Lambda 표현식으로도 수행할 수 있습니다.
- "효과적인 최종" 지역 변수는 물론 외부 클래스의 멤버 변수에도 직접 액세스할 수 있습니다(인스턴스 변수 및 클래스 변수 포함, 물론 클래스 메서드에서는 클래스 변수에만 액세스할 수 있습니다).
- 생성된 객체는 인터페이스에서 상속된 기본 메서드를 직접 호출할 수 있습니다.
람다 표현식 및 주석
람다 표현식은 기능적 인터페이스의 구현 클래스 객체로만 사용될 수 있기 때문에 기능적 인터페이스 정의 전에 주석을 추가할 수 있으며, 인터페이스가 기능적 인터페이스가 아닌 경우 오류가 보고됩니다.
주석: @FunctionalInterface