java 8 버전을 꽤 오래 사용했었는데, 제대로 공부한 적이 없는 것 같아 조금씩 정리해보는 포스팅을 써본다.
함수형 인터페이스 (Functional Interface)
https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8
Chapter 9. Interfaces
If a single field is inherited multiple times from the same interface because, for example, both this interface and one of this interface's direct superinterfaces extend the interface that declares the field, then only a single member results. This situati
docs.oracle.com
- Default 메소드 이외 단 한 개의 추상 메서드를 가지는 인터페이스
- @FunctionalInterface 어노테이션이 붙은 인터페이스. @FunctionalInterface 어노테이션을 명시적으로 붙임으로써, 컴파일러에게는 해당 인터페이스가 함수형 인터페이스임을 알리고, 추상 메서드를 여러 개 작성하는 경우 또는 해당 인터페이스를 상속하는 경우 컴파일 단계에서 에러를 뱉게 된다.
- 기존에는 자바에서는 기본 데이터 타입들만 값으로 판단하였지만 (ex: Integer, int, Long, String), 함수형 인터페이스 등장으로 인해 함수도 값으로 판단할 수 있게 되었다. 함수 또한 값으로 판단하게 되어 유연한 코드 작성이 가능해졌다.
함수형 인터페이스 선언 예시
package com.tistory.johnmark.functional;
@FunctionalInterface
public interface Validator {
boolean match();
}
함수형 인터페이스인데 추상 메소드가 한 개 이상인 경우 에러 발생
package com.tistory.johnmark.functional;
@FunctionalInterface
public interface Validator {
boolean match();
void print();
}
추상 메소드가 한 개라면 default 메소드나 static 메소드는 상관 없음
package com.tistory.johnmark.functional;
@FunctionalInterface
public interface Validator {
static void printClassName() {
System.out.println("Validator");
}
default String getClassName() {
return "Validator";
}
boolean match();
}
java8 부터는 interface에 default 키워드를 붙인 메소드를 선언할 수 있게 되었다. default 키워드가 붙은 메소드는
해당 인터페이스를 구현한 모든 구현체에 적용이된다.
활용 예시
package com.tistory.johnmark.functional;
import java.util.Arrays;
import java.util.List;
public class FunctionalInterfaceTest {
public static void main(String[] args) {
List<String> names = Arrays.asList("JohnMark", "JeongHyeon", "Bob", "Mark", "Richard", "Narisa");
List<Integer> scores = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80, 95, 100);
for (String name : names) {
// 함수형 인터페이스를 통해 함수자체를 값으로 넘김
if (isValid(() -> name.startsWith("J"))) {
System.out.printf("Matched Name: [%s]\n", name);
}
}
System.out.println("------------------------------------------");
for (int score : scores) {
// 함수형 인터페이스를 통해 함수자체를 값으로 넘김
if (isValid(() -> score > 50)) {
System.out.printf("Matched Score: [%d]\n", score);
}
}
}
public static boolean isValid(Validator validator) {
return validator.match();
}
}
함수를 값으로 넘겨줄 수 있게 됨으로써, isValid 메소드의 인자인 함수형 인터페이스 Validator의 인스턴스를 람다 표현식으로 만들어 넘김으로 써, 함수형 인터페이스의 추상 메서드 내용을 String, Integer 등 다양한 데이터 타입에 대해 원하는 로직 (1. J로 시작하는 문자열, 2. 50보다 큰 숫자)을 유연하게 작성하고 적용할 수 있게 되었다.
람다 표현식 (Lambda Expressions)https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27
Chapter 15. Expressions
docs.oracle.com
- 람다 표현식은 메소드와 비슷함 (매개변수, 매개변수가 사용되는 body block)
- 간결한 코드 작성 가능
- 함수를 만드는 과정 없이 한 번에 처리 가능
- 람다 표현식을 사용하면서 만드는 무명 함수는 재사용이 불가능함
- 디버깅이 어려움
형태
LambdaExpression:
LambdaParameters -> LambdaBody
예시
() -> {} // No parameters; result is void
() -> 42 // No parameters, expression body
() -> null // No parameters, expression body
() -> { return 42; } // No parameters, block body with return
() -> { System.gc(); } // No parameters, void block body
() -> { // Complex block body with returns
if (true) return 12;
else {
int result = 15;
for (int i = 1; i < 10; i++)
result *= i;
return result;
}
}
(int x) -> x+1 // Single declared-type parameter
(int x) -> { return x+1; } // Single declared-type parameter
(x) -> x+1 // Single inferred-type parameter
x -> x+1 // Parentheses optional for
// single inferred-type parameter
(String s) -> s.length() // Single declared-type parameter
(Thread t) -> { t.start(); } // Single declared-type parameter
s -> s.length() // Single inferred-type parameter
t -> { t.start(); } // Single inferred-type parameter
(int x, int y) -> x+y // Multiple declared-type parameters
(x, y) -> x+y // Multiple inferred-type parameters
(x, int y) -> x+y // Illegal: can't mix inferred and declared types
(x, final y) -> x+y // Illegal: no modifiers with inferred types
출처
https://docs.oracle.com/javase/specs/jls/se8/html/
The Java® Language Specification
James Gosling Bill Joy Guy Steele Gilad Bracha Alex Buckley
docs.oracle.com
'Programming > Java' 카테고리의 다른 글
[백 투 더 베이직] 객체지향 SOLID 원칙 (0) | 2021.07.19 |
---|---|
[삽질일기] Arrays.asList 와 ArrayList의 차이 (1) | 2021.07.17 |
객체, 클래스 그리고 인스턴스 (0) | 2021.06.15 |
[Java] CMD 또는 Shell 환경에서 Java 컴파일 및 Jar 파일 만들기 (0) | 2021.01.12 |
[Java8] 윤년, 다음달 말일 계산 (0) | 2020.07.17 |
java 8 버전을 꽤 오래 사용했었는데, 제대로 공부한 적이 없는 것 같아 조금씩 정리해보는 포스팅을 써본다.
함수형 인터페이스 (Functional Interface)
https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.8
Chapter 9. Interfaces
If a single field is inherited multiple times from the same interface because, for example, both this interface and one of this interface's direct superinterfaces extend the interface that declares the field, then only a single member results. This situati
docs.oracle.com
- Default 메소드 이외 단 한 개의 추상 메서드를 가지는 인터페이스
- @FunctionalInterface 어노테이션이 붙은 인터페이스. @FunctionalInterface 어노테이션을 명시적으로 붙임으로써, 컴파일러에게는 해당 인터페이스가 함수형 인터페이스임을 알리고, 추상 메서드를 여러 개 작성하는 경우 또는 해당 인터페이스를 상속하는 경우 컴파일 단계에서 에러를 뱉게 된다.
- 기존에는 자바에서는 기본 데이터 타입들만 값으로 판단하였지만 (ex: Integer, int, Long, String), 함수형 인터페이스 등장으로 인해 함수도 값으로 판단할 수 있게 되었다. 함수 또한 값으로 판단하게 되어 유연한 코드 작성이 가능해졌다.
함수형 인터페이스 선언 예시
package com.tistory.johnmark.functional;
@FunctionalInterface
public interface Validator {
boolean match();
}
함수형 인터페이스인데 추상 메소드가 한 개 이상인 경우 에러 발생
package com.tistory.johnmark.functional;
@FunctionalInterface
public interface Validator {
boolean match();
void print();
}
추상 메소드가 한 개라면 default 메소드나 static 메소드는 상관 없음
package com.tistory.johnmark.functional;
@FunctionalInterface
public interface Validator {
static void printClassName() {
System.out.println("Validator");
}
default String getClassName() {
return "Validator";
}
boolean match();
}
java8 부터는 interface에 default 키워드를 붙인 메소드를 선언할 수 있게 되었다. default 키워드가 붙은 메소드는
해당 인터페이스를 구현한 모든 구현체에 적용이된다.
활용 예시
package com.tistory.johnmark.functional;
import java.util.Arrays;
import java.util.List;
public class FunctionalInterfaceTest {
public static void main(String[] args) {
List<String> names = Arrays.asList("JohnMark", "JeongHyeon", "Bob", "Mark", "Richard", "Narisa");
List<Integer> scores = Arrays.asList(10, 20, 30, 40, 50, 60, 70, 80, 95, 100);
for (String name : names) {
// 함수형 인터페이스를 통해 함수자체를 값으로 넘김
if (isValid(() -> name.startsWith("J"))) {
System.out.printf("Matched Name: [%s]\n", name);
}
}
System.out.println("------------------------------------------");
for (int score : scores) {
// 함수형 인터페이스를 통해 함수자체를 값으로 넘김
if (isValid(() -> score > 50)) {
System.out.printf("Matched Score: [%d]\n", score);
}
}
}
public static boolean isValid(Validator validator) {
return validator.match();
}
}
함수를 값으로 넘겨줄 수 있게 됨으로써, isValid 메소드의 인자인 함수형 인터페이스 Validator의 인스턴스를 람다 표현식으로 만들어 넘김으로 써, 함수형 인터페이스의 추상 메서드 내용을 String, Integer 등 다양한 데이터 타입에 대해 원하는 로직 (1. J로 시작하는 문자열, 2. 50보다 큰 숫자)을 유연하게 작성하고 적용할 수 있게 되었다.
람다 표현식 (Lambda Expressions)https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27
Chapter 15. Expressions
docs.oracle.com
- 람다 표현식은 메소드와 비슷함 (매개변수, 매개변수가 사용되는 body block)
- 간결한 코드 작성 가능
- 함수를 만드는 과정 없이 한 번에 처리 가능
- 람다 표현식을 사용하면서 만드는 무명 함수는 재사용이 불가능함
- 디버깅이 어려움
형태
LambdaExpression:
LambdaParameters -> LambdaBody
예시
() -> {} // No parameters; result is void
() -> 42 // No parameters, expression body
() -> null // No parameters, expression body
() -> { return 42; } // No parameters, block body with return
() -> { System.gc(); } // No parameters, void block body
() -> { // Complex block body with returns
if (true) return 12;
else {
int result = 15;
for (int i = 1; i < 10; i++)
result *= i;
return result;
}
}
(int x) -> x+1 // Single declared-type parameter
(int x) -> { return x+1; } // Single declared-type parameter
(x) -> x+1 // Single inferred-type parameter
x -> x+1 // Parentheses optional for
// single inferred-type parameter
(String s) -> s.length() // Single declared-type parameter
(Thread t) -> { t.start(); } // Single declared-type parameter
s -> s.length() // Single inferred-type parameter
t -> { t.start(); } // Single inferred-type parameter
(int x, int y) -> x+y // Multiple declared-type parameters
(x, y) -> x+y // Multiple inferred-type parameters
(x, int y) -> x+y // Illegal: can't mix inferred and declared types
(x, final y) -> x+y // Illegal: no modifiers with inferred types
출처
https://docs.oracle.com/javase/specs/jls/se8/html/
The Java® Language Specification
James Gosling Bill Joy Guy Steele Gilad Bracha Alex Buckley
docs.oracle.com
'Programming > Java' 카테고리의 다른 글
[백 투 더 베이직] 객체지향 SOLID 원칙 (0) | 2021.07.19 |
---|---|
[삽질일기] Arrays.asList 와 ArrayList의 차이 (1) | 2021.07.17 |
객체, 클래스 그리고 인스턴스 (0) | 2021.06.15 |
[Java] CMD 또는 Shell 환경에서 Java 컴파일 및 Jar 파일 만들기 (0) | 2021.01.12 |
[Java8] 윤년, 다음달 말일 계산 (0) | 2020.07.17 |