1. 개요
이 기사에서는 Java 8에서 가장 흥미로운 몇 가지 새로운 기능에 대해 간략히 살펴 보겠습니다.
인터페이스 기본 및 정적 메서드, 메서드 참조 및 선택 사항에 대해 설명합니다.
Java 8 릴리스의 일부 기능인 스트림 API , 람다 표현식 및 기능적 인터페이스 는 별도의 모양이 필요한 포괄적 인 주제이므로 이미 다루었습니다 .
2. 인터페이스 기본 및 정적 방법
Java 8 이전에는 인터페이스에 공용 추상 메서드 만있을 수있었습니다. 모든 구현 클래스가 새 메서드의 구현을 만들도록 강제하지 않고는 기존 인터페이스에 새 기능을 추가 할 수 없었으며 구현을 통해 인터페이스 메서드를 만들 수도 없었습니다.
Java 8부터 인터페이스는 인터페이스 에서 선언 되었음에도 불구하고 정의 된 동작을 갖는 정적 및 기본 메소드를 가질 수 있습니다 .
2.1. 정적 방법
인터페이스의 다음 메소드를 고려하십시오 (이 인터페이스를 Vehicle 이라고 부르겠습니다 ).
static String producer() {
return "N&F Vehicles";
}
정적 생산자 () 메서드는 인터페이스 내부와 내부에서만 사용할 수 있습니다. 구현 클래스로 재정의 할 수 없습니다.
인터페이스 외부에서 호출하려면 정적 메서드 호출에 대한 표준 접근 방식을 사용해야합니다.
String producer = Vehicle.producer();
2.2. 기본 방법
기본 메서드는 새로운 기본 키워드를 사용하여 선언됩니다 . 이들은 구현 클래스의 인스턴스를 통해 액세스 할 수 있으며 재정의 할 수 있습니다.
Vehicle 인터페이스에 기본 메소드를 추가 하여이 인터페이스 의 정적 메소드도 호출합니다 .
default String getOverview() {
return "ATV made by " + producer();
}
이 인터페이스가 VehicleImpl 클래스에 의해 구현되었다고 가정합니다 . 기본 메서드 를 실행하려면 이 클래스의 인스턴스를 만들어야합니다.
Vehicle vehicle = new VehicleImpl();
String overview = vehicle.getOverview();
3. 방법 참조
메서드 참조는 기존 메서드 만 호출하는 람다 식에 대한 더 짧고 읽기 쉬운 대안으로 사용할 수 있습니다. 메서드 참조에는 네 가지 변형이 있습니다.
3.1. 정적 메서드에 대한 참조
정적 메서드에 대한 참조에는 ContainingClass :: methodName 구문이 포함됩니다.
Stream API를 사용 하여 List <String> 의 모든 빈 문자열을 계산해 보겠습니다 .
boolean isReal = list.stream().anyMatch(u -> User.isRealUser(u));
anyMatch () 메서드 에서 람다 식을 자세히 살펴보면 User 클래스 의 정적 메서드 isRealUser (User user) 를 호출 할뿐입니다 . 따라서 정적 메서드에 대한 참조로 대체 할 수 있습니다.
boolean isReal = list.stream().anyMatch(User::isRealUser);
이 유형의 코드는 훨씬 더 많은 정보를 제공합니다.
3.2. 인스턴스 메서드에 대한 참조
인스턴스 메소드에 대한 참조는 다음 구문을 보유합니다. c ontainingInstance :: methodName. 다음 코드 는 입력 매개 변수의 유효성을 검사하는 User 유형의 isLegalName (String string) 메소드를 호출합니다 .
User user = new User();
boolean isLegalName = list.stream().anyMatch(user::isLegalName);
3.3. 특정 유형의 개체의 인스턴스 메서드에 대한 참조
이 참조 메소드는 다음 구문을 사용합니다. C ontainingType :: methodName. 예 ::
long count = list.stream().filter(String::isEmpty).count();
3.4. 생성자에 대한 참조
생성자에 대한 참조는 다음 구문을 사용합니다. ClassName :: new. Java의 생성자는 특별한 메서드이므로 new as a method name을 사용하여 메서드 참조를 적용 할 수도 있습니다 .
Stream<User> stream = list.stream().map(User::new);
4. 옵션 <T>
Java 8 개발자는 NullPointerException (NPE) 이 발생할 가능성이 있으므로 자신이 참조한 값의 유효성을주의 깊게 확인해야했습니다 . 이러한 모든 검사에는 매우 성 가시고 오류가 발생하기 쉬운 상용구 코드가 필요했습니다.
Java 8 Optional <T> 클래스는 NPE 를 얻을 가능성이있는 상황을 처리하는 데 도움이 될 수 있습니다 . T 유형의 개체에 대한 컨테이너로 작동 합니다.이 값이 null 이 아닌 경우이 개체의 값을 반환 할 수 있습니다 . 이 컨테이너 내부의 값이 null이면 NPE 를 던지는 대신 미리 정의 된 작업을 수행 할 수 있습니다 .
4.1. 의 생성 옵션 <T>
Optional 클래스 의 인스턴스 는 정적 메서드를 사용하여 만들 수 있습니다.
Optional<String> optional = Optional.empty();
빈 옵션을 반환합니다 .
String str = "value";
Optional<String> optional = Optional.of(str);
null이 아닌 값을 포함 하는 Optional 을 반환합니다 .
Optional<String> optional = Optional.ofNullable(getString());
반환 옵션을 특정 값 또는 빈과 선택적 매개 변수 인 경우 는 null.
4.2. 선택적 <T> 사용법
예를 들어 List <String> 을 가져올 것으로 예상하고 null 의 경우 ArrayList <String> 의 새 인스턴스로 대체하려고합니다 . W i 번째 8의 코드 자바를 사전에이 같은 것을 할 필요가 :
List<String> list = getList();
List<String> listOpt = list != null ? list : new ArrayList<>();
Java 8에서는 훨씬 짧은 코드로 동일한 기능을 얻을 수 있습니다.
List<String> listOpt = getList().orElseGet(() -> new ArrayList<>());
예전 방식으로 어떤 객체의 필드에 도달해야 할 때 더 많은 상용구 코드가 있습니다. 이 타입의 객체가 가정 사용자 타입의 필드가 주소 필드의와 treet 유형의 문자열. 그리고 어떤 이유로 거리 필드 의 값이 있으면 반환해야하고 거리 가 null이면 기본값 을 반환해야합니다 .
User user = getUser();
if (user != null) {
Address address = user.getAddress();
if (address != null) {
String street = address.getStreet();
if (street != null) {
return street;
}
}
}
return "not specified";
선택 사항 으로 단순화 할 수 있습니다 .
Optional<User> user = Optional.ofNullable(getUser());
String result = user
.map(User::getAddress)
.map(Address::getStreet)
.orElse("not specified");
이 예에서 우리는 사용 Map () 호출의 변환 결과에 방법을 getAdress ()를 받는 옵션 <주소> 와 getStreet () 에 선택적 <문자열>. 이러한 메서드 중 하나가 null을 반환 하면 map () 메서드는 빈 Optional을 반환합니다 .
getter가 Optional <T>를 반환한다고 상상해보십시오 . 따라서 map () 대신 flatMap () 메서드를 사용해야합니다 .
Optional<OptionalUser> optionalUser = Optional.ofNullable(getOptionalUser());
String result = optionalUser
.flatMap(OptionalUser::getAddress)
.flatMap(OptionalAddress::getStreet)
.orElse("not specified");
Optional의 또 다른 사용 사례는 또 다른 예외를 제외 하고 NPE 를 변경하는 것 입니다. 따라서 이전에했던 것처럼 Java 8 이전 스타일로이를 시도해 보겠습니다.
String value = null;
String result = "";
try {
result = value.toUpperCase();
} catch (NullPointerException exception) {
throw new CustomException();
}
그리고 Optional <String>을 사용하면 어떨까요? 대답은 더 읽기 쉽고 간단합니다.
String value = null;
Optional<String> valueOpt = Optional.ofNullable(value);
String result = valueOpt.orElseThrow(CustomException::new).toUpperCase();
앱에서 선택 사항 을 사용하는 방법과 목적 은 심각하고 논란이 많은 디자인 결정이며 모든 장단점에 대한 설명은이 문서의 범위를 벗어납니다. 관심이 있다면 더 깊이 파고들 수 있습니다. 인터넷에는이 문제에 관한 흥미로운 기사가 많이 있습니다. 이것 과 이것 하나 가 매우 도움이 될 수 있습니다.
5. 결론
이 기사에서는 Java 8의 몇 가지 흥미로운 새 기능에 대해 간략하게 설명합니다.
물론 많은 Java 8 JDK 패키지 및 클래스에 퍼져있는 다른 많은 추가 및 개선 사항이 있습니다.
그러나이 기사에 설명 된 정보는 이러한 새로운 기능 중 일부를 탐색하고 학습하기위한 좋은 출발점입니다.
- https://docs.spring.io/spring-framework/docs/current/reference/html
- https://www.baeldung.com/java-8-new-features
'Java' 카테고리의 다른 글
WebRTC 사용방법(예제) (1) | 2021.03.21 |
---|---|
자바 컬렉션 (0) | 2021.03.21 |
Java 14의 새로운 기능 (0) | 2021.03.21 |
Spring을 사용한 기능 플래그 (0) | 2021.03.20 |
PowerMock 소개 (0) | 2021.03.20 |