Java java지도 시간 Java8 사용을 위한 올바른 자세

Java8 사용을 위한 올바른 자세

Jan 18, 2017 pm 03:24 PM

Java 프로그래밍 언어

Java는 크로스 플랫폼 응용 소프트웨어를 작성할 수 있는 객체 지향 프로그래밍 언어로 1995년 5월 Sun Microsystems에서 출시한 Java 프로그래밍 언어이자 Java 플랫폼입니다. JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))의 총칭.


우리는 Java 8에 몇 가지 매우 유용한 API가 추가되었다는 것을 알고 있으며 그 중 하나는 Optional입니다. 조금만 살펴보지 않으면 가볍게 생각할 수 있습니다. NullPointException.문제를 우아하게 해결해서 이렇게 코드가 작성되기 시작했습니다

Optional<User> user = ……
if (user.isPresent()) {
return user.getOrders();
} else {
return Collections.emptyList();
}
로그인 후 복사

그렇다면 우리의 생각은 여전히 ​​같은 곳에 있다고 해야 하지만 본능적으로는 User를 위한 래퍼일 뿐이라고 생각합니다.

User user = …..
if (user != null) {
return user.getOrders();
} else {
return Collections.emptyList();
}
로그인 후 복사

본질적으로는 차이가 없습니다. 이것이 우리가 이야기할 Java 8 Optional Type을 사용하는 올바른 자세입니다.

리우올림픽에서도 오성홍기에 문제가 있다고 뉴스에서 반복적으로 언급했는데, 아무리 봐도 잘못된 게 보이지 않았으나 나중에 보니 작은 별이 중심을 숭배하는 자세였다. 그러므로 우리는 익숙한 것을 당연하게 여겨서는 안 되며, 전혀 잘못된 것을 느끼지 않을 것입니다. 즉, Java 8 Optional로 전환하면 이전에 처리했던 방식을 상속받을 수 없습니다. null 과거에는 Java 8 Optional을 올바르게 사용하는 새롭고 올바른 자세를 익혀야 합니다.

직설적으로 말하면, 여전히 다음과 같은 Optional을 사용하고 있을 때 우리는 스스로 점검을 시작해야 합니다. 🎜>

isPresent() 메소드 호출 시

get() 메소드 호출 시

옵션 유형 클래스/인스턴스 속성으로 사용 시

옵션 유형 시 메소드 매개변수

isPresent() 및 obj != null 차이가 없습니다. 경고를 수신하는 get() 호출의 길을 열어주는 isPresent()가 없으면 우리 삶은 여전히 ​​충격적입니다. IntelliJ IDEA

Reports calls to java.util.Optional.get() without first checking with a isPresent() 
call if a value is available. If the Optional does not contain a value, get() will throw an exception. 
(调用 Optional.get() 前不事先用 isPresent() 检查值是否可用. 假如 Optional 不包含一个值, get() 将会抛出一个异常)
로그인 후 복사

IntelliJ IDEA에서는 Optional 유형을 속성이나 메소드 매개변수로 사용하는 것을 강력히 권장하지 않습니다

Reports any uses of java.util.Optional<T>, java.util.OptionalDouble, java.util.OptionalInt, 
java.util.OptionalLong or com.google.common.base.Optional as the type for a field or a parameter. Optional was designed
 to provide a limited mechanism for library method return types where there needed to be a clear way to represent 
 “no result”. Using a field with type java.util.Optional is also problematic if the class needs to be Serializable, 
 which java.util.Optional is not. (使用任何像 Optional 的类型作为字段或方法参数都是不可取的. Optional 只设计为类库方法的,
  可明确表示可能无值情况下的返回类型. Optional 类型不可被序列化, 用作字段类型会出问题的)
로그인 후 복사

따라서 Optional에서 실제로 신뢰할 수 있는 것은 isPresent() 및 get():

공용 선택적 맵(함수 매퍼)

공용 T orElse(T 기타)

public T orElseGet(공급자 기타 확장)

public void ifPresent(Consumer 소비자)

public Optional 필터(Predicate predicate)

public Optional flatMap(Functionpublic (Supplier< ? 확장 X> 예외 공급업체)는 서문을 발생시킵니다.

먼저 Optional.of(obj), Optional.ofNullable(obj) 및 명시적인 Optional.empty()의 세 가지 구성 방법을 언급해야 합니다.

Optional.of(obj): 들어오는 obj가 null일 수 없어야 합니다. 그렇지 않으면 역할을 입력하기 전에 NullPointerException이 발생합니다.

Optional.ofNullable(obj): 지능적인 방법을 사용합니다. , Optional 인스턴스를 생성하는 관용적인 방법입니다. 모든 사용자를 환영합니다. null을 전달하면 Optional.empty()를 얻게 됩니다. null이 아닌 경우 Optional.of(obj)를 호출하세요.

그게 바로 그 것입니다. 그냥 Optional.ofNullable(obj)을 사용하고 변경되지 않고 두 번째 변경 사항에 적응하는 방식으로 Optional 인스턴스를 구성하면 됩니다. 그렇지 않으면 왜 Optional.of를 사용합니까? (obj) 너무 노출되나요? 비공개일 수 있나요?

제 개인적인 관점은 다음과 같습니다. 1. Optional.of(obj)에 전달할 obj 매개변수가 매우 명확할 때 null, 예를 들어 방금 새로운 객체(Optional.of(new User( ...)))이거나 null이 아닌 상수입니다. 2. obj가 null이 아니라고 주장하려는 경우 즉, NullPointException 예외를 즉시 보고하고 obj가 null인 경우 Null 포인터 예외를 숨기는 대신 즉시 수정하고 싶습니다. Optional에 숨길 수 있는 기회를 이용하기 위해 값을 사용합니다.

지금 사용하는 방법 기존 Optional 인스턴스, Optional 사용자 인스턴스가 있다고 가정할 경우 다음과 같은 경우를 피하는 몇 가지 일반적인 방법이 있습니다. (user.isPresent()) { ... } else { ... } .

존재하면 반환되고, 없으면 기본값 제공

return user.orElse(null);  //而不是 return user.isPresent() ? user.get() : null;
return user.orElse(UNKNOWN_USER);
로그인 후 복사

존재하면 반환되고, 존재하지 않으면 함수에 의해 생성됩니다

return user.orElseGet(() -> fetchAUserFromDatabase()); //而不要 return user.isPresent() ? user: fetchAUserFromDatabase();
로그인 후 복사

存在才对它做点什么

user.ifPresent(System.out::println);

//而不要下边那样
if (user.isPresent()) {
  System.out.println(user.get());
}
로그인 후 복사

map 函数隆重登场

当 user.isPresent() 为真, 获得它关联的 orders, 为假则返回一个空集合时, 我们用上面的 orElse, orElseGet 方法都乏力时, 那原本就是 map 函数的责任, 我们可以这样一行

return user.map(u -> u.getOrders()).orElse(Collections.emptyList())

//上面避免了我们类似 Java 8 之前的做法
if(user.isPresent()) {
  return user.get().getOrders();
} else {
  return Collections.emptyList();
}
로그인 후 복사

map 是可能无限级联的, 比如再深一层, 获得用户名的大写形式

return user.map(u -> u.getUsername())
           .map(name -> name.toUpperCase())
           .orElse(null);
로그인 후 복사

这要搁在以前, 每一级调用的展开都需要放一个 null 值的判断

User user = .....
if(user != null) {
  String name = user.getUsername();
  if(name != null) {
    return name.toUpperCase();
  } else {
    return null;
  }
} else {
  return null;
}
로그인 후 복사

针对这方面 Groovy 提供了一种安全的属性/方法访问操作符 ?.

user?.getUsername()?.toUpperCase();
로그인 후 복사

Swift 也有类似的语法, 只作用在  Optional 的类型上.

用了 isPresent() 处理 NullPointerException 不叫优雅, 有了  orElse, orElseGet 等, 特别是 map 方法才叫优雅.

其他几个, filter() 把不符合条件的值变为 empty(),  flatMap() 总是与 map() 方法成对的,  orElseThrow() 在有值时直接返回, 无值时抛出想要的异常.

一句话小结: 使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法.

最后, 最好的理解 Java 8 Optional 的方法莫过于看它的源代码 java.util.Optional, 阅读了源代码才能真真正正的让你解释起来最有底气, Optional 的方法中基本都是内部调用  isPresent() 判断, 真时处理值, 假时什么也不做.

以上就是使用 Java8 Optional 的正确姿势的内容,更多相关内容请关注PHP中文网(www.php.cn)!


본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Java 8에서 1년 전 또는 1년 후의 날짜를 어떻게 계산합니까? Java 8에서 1년 전 또는 1년 후의 날짜를 어떻게 계산합니까? Apr 26, 2023 am 09:22 AM

Java8은 1년 전 날짜를 계산하기 위해 minus() 메소드를 사용하여 1년 전 또는 1년 후 날짜를 계산합니다. packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo09{publicstaticvoidmain(String[ ]args ){LocalDatetoday=LocalDate.now();LocalDatepreviousYear=today.minus(1,ChronoUni

Java에서 일반적으로 사용되는 Optional 메소드는 무엇입니까? Java에서 일반적으로 사용되는 Optional 메소드는 무엇입니까? May 09, 2023 am 11:34 AM

머리말 Java의 Optional은 null이 아닌 값을 포함하거나 비어 있을 수 있는 컨테이너 개체입니다. 주요 목적은 코드를 작성할 때 널 포인터 예외를 방지하는 것입니다. java8에서 Optional의 전체 사용법은 다음과 같습니다. 1. Optional 객체를 생성합니다. of() 메소드를 통해 null이 아닌 값을 포함하는 Optional 객체를 생성할 수 있습니다. 예: OptionalOptional=Optional.of("value") ; ofNullable() 메소드를 통해 생성될 수도 있습니다. null 값을 포함하는 Optional 객체입니다. 예: OptionalOptional=Optiona

Java 8을 사용하여 일주일 후 날짜를 계산하는 방법은 무엇입니까? Java 8을 사용하여 일주일 후 날짜를 계산하는 방법은 무엇입니까? Apr 21, 2023 pm 11:01 PM

Java8에서 일주일 후 날짜를 계산하는 방법 이 예에서는 일주일 후 날짜를 계산합니다. LocalDate 날짜에는 시간 정보가 포함되어 있지 않습니다. 해당 plus() 메서드는 일, 주 및 월을 추가하는 데 사용됩니다. ChronoUnit 클래스는 이러한 시간 단위를 선언합니다. LocalDate도 불변형이므로 반환 후 값을 할당하려면 변수를 사용해야 합니다. packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.temporal.ChronoUnit;publicclassDemo08{publicstaticvoidmain(String[

Java8에서 Clock 클래스를 사용하는 방법 Java8에서 Clock 클래스를 사용하는 방법 Apr 25, 2023 pm 03:37 PM

Java8의 Clock 클래스 Java8은 현재 타임스탬프 또는 현재 시간대의 날짜 및 시간 정보를 얻기 위해 Clock 클래스를 추가합니다. 이전에는 System.currentTimeInMillis() 및 TimeZone.getDefault()를 사용했지만 Clock으로 대체할 수 있습니다. packagecom.shxt.demo02;importjava.time.Clock;publicclassDemo10{publicstaticvoidmain(String[]args){//현재 시간 기준을 반환합니다.

Java에서 Optional 함수를 사용하여 null 값 사례를 처리하는 방법 Java에서 Optional 함수를 사용하여 null 값 사례를 처리하는 방법 Oct 20, 2023 am 10:06 AM

Optional 함수를 사용하여 Java에서 Null 값을 처리하는 방법 Java 프로그래밍에서는 Null 값이 처리되는 상황에 자주 직면합니다. 널 포인터 예외는 이러한 상황을 피하기 위해 일반적인 오류입니다. Java8에서는 널 값 상황을 처리하기 위해 Optional 클래스를 도입했습니다. Optional 클래스는 비어 있지 않은 값을 포함하거나 값이 없을 수 있는 컨테이너 클래스입니다. Optional 클래스를 사용하면 null 값 상황을 보다 적절하게 처리하고 null 포인터 예외를 방지할 수 있습니다. 아래에

Java8에서 시간대를 처리하는 방법 Java8에서 시간대를 처리하는 방법 Apr 27, 2023 pm 09:22 PM

Java 8에서 시간대 처리 Java 8은 날짜와 시간을 분리할 뿐만 아니라 시간대도 분리합니다. 이제 특정 시간대를 처리하는 ZoneId 및 특정 시간대의 시간을 나타내는 ZoneDateTime과 같은 일련의 별도 클래스가 있습니다. 이는 Java8 이전의 GregorianCalendar 클래스에 의해 수행되었습니다. 다음 예에서는 이 시간대의 시간을 다른 시간대의 시간으로 변환하는 방법을 보여줍니다. packagecom.shxt.demo02;importjava.time.LocalDateTime;importjava.time.ZoneId;importjava.time.ZonedDateT

Java8에서 현재 타임스탬프를 얻는 방법 Java8에서 현재 타임스탬프를 얻는 방법 May 01, 2023 am 11:46 AM

Java8에서 현재 타임스탬프를 가져옵니다. Instant 클래스에는 아래와 같이 현재 타임스탬프를 반환하는 정적 팩터리 메서드 now()가 있습니다. packagecom.shxt.demo02;importjava.time.Instant;publicclassDemo16{publicstaticvoidmain(String[]args) {Instanttimestamp=Instant.now();System.out.println("Thisinstant의 값은 무엇입니까"+timestamp.t

사전 정의된 형식 지정 도구를 사용하여 Java8에서 날짜를 구문 분석하거나 형식 지정하는 방법 사전 정의된 형식 지정 도구를 사용하여 Java8에서 날짜를 구문 분석하거나 형식 지정하는 방법 Apr 28, 2023 pm 07:40 PM

사전 정의된 형식화 도구를 사용하여 Java 8에서 날짜를 구문 분석하거나 형식화하는 방법 packagecom.shxt.demo02;importjava.time.LocalDate;importjava.time.format.DateTimeFormatter;publicclassDemo17{publicstaticvoidmain(String[]args){StringdayAfterTommorrow="20180205 "; LocalDateformatted=LocalDate.parse

See all articles