Trước Java 8, nếu chúng ta muốn kiểm tra xem một cái gì đó có giá trị rỗng hay không, chúng ta phải viết các lệnh kiểm tra rỗng. Ngày nay, chúng tôi có những lựa chọn thay thế tốt hơn.

Hãy xem xét một tình huống khi chúng tôi có một phương pháp trả về một biểu trưng từ Person. Thật không may, chúng tôi không biết liệu người đó có tồn tại hay không (trong trường hợp này, chúng tôi muốn có biểu tượng mặc định), vì vậy chúng tôi phải kiểm tra xem Person không phải vô giá trị:

  public Logo getLogoOrReturnDefault(Person person) {
    if(person != null) {
        return person.getLogo();
    }
    return new DefaultLogo();
}

Được rồi, chúng tôi đã kiểm tra và chúng tôi rất vui vì mã của chúng tôi không bị lỗi do NPE. Chúng ta cũng có thể bỏ qua điều này bằng cách sử dụng danh sách Người thay vì đối tượng đơn lẻ và thực hiện bước trước. Chúng tôi cũng có thể kiểm tra xem danh sách có trống không trước khi làm bất cứ điều gì. Một giải pháp khác là chúng tôi có thể cấu trúc lại mã của mình để sử dụng NullObject họa tiết. Cuối cùng, chúng ta có thể mắc phải quy tắc nhanh không thành công – không kiểm tra và NPE khi nào Person vô giá trị. NHƯNG chúng tôi có Java 8 trong dự án của mình, vì vậy có một thứ đặc biệt gọi là Tùy chọn. Được rồi, tuyệt vời, chúng tôi lấy đối tượng đó và cấu trúc lại mã của chúng tôi theo các tiêu chuẩn Java 8:

  public Logo getLogoOrReturnDefault(Person person) {
    Optional<Person> optionalPerson = Optional.ofNullable(person);
    if(optionalPerson.isPresent()) {
        return optionalPerson.get().getLogo();
    }
    return new DefaultLogo();
}

Tốt, không có null trong mã của chúng tôi. Nó tốt hơn trước? Không. Nó dễ đọc hơn? Không hẳn vậy. Chúng ta có thể làm điều đó tốt hơn không? Đúng!
Tôi đã thấy cái này wannabe-refactor nhiều lần. Trước khi chúng tôi tạo ra một giải pháp tốt hơn, tôi muốn chia sẻ một ví dụ khác về nice sử dụng Tùy chọn.

  final Optional<Person> bigPerson = members.stream()
    .filter(member -> member.getLevel() > 10)
    .findFirst();
if (bigPerson.isPresent()) {
    //many lines of code here
    return something;
} else {
    return another;
}

Tất nhiên, tôi biết tại sao ai đó lại viết ra sinh vật xấu xí này. Đơn giản là họ không biết các Đối tượng tùy chọn có sức mạnh như thế nào và làm thế nào để sử dụng nó để cải thiện khả năng đọc của mã. Theo tôi, thuộc tính tốt nhất của Optional không phải là ẩn null hoặc nói rằng phương thức của chúng tôi có thể trả về một cái gì đó hoặc không. Tính năng lớn nhất mà Tùy chọn mang lại cho chúng tôi là chuyển đổi. Chúng tôi không chỉ đơn giản kiểm tra xem một đối tượng Tùy chọn có trống hay không. Chúng tôi có thể biến đổi nó thành những gì chúng tôi muốn (bao nhiêu lần tùy thích) trong một vài dòng và cung cấp các giải pháp thay thế khi một trong các bước chuyển đổi không trả lại kết quả hiện có. Vì vậy, thay vì kiểm tra khi con người của chúng ta tồn tại với isPresent()chung ta co thể lam được việc nay:

  public Logo getLogoOrReturnDefault(Person person) {
    return Optional.ofNullable(person)
        .map(p -> p.getLogo())
        .orElse(new DefaultLogo());
}

Và một ví dụ thứ hai:

  final Optional<Person> highLevelPerson = members.stream()
    .filter(member -> member.getLevel() > 10)
    .findFirst()
    .map(member -> privateMethodFromManyLinesOfCode(member))
    .orElse(another);

Đây là một ví dụ rất đơn giản, nhưng chúng ta có thể thực hiện nhiều thao tác bản đồ hơn hoặc thêm nhiều thao tác lọc. Chúng ta có thể làm bất cứ điều gì chúng ta muốn mà không cần câu lệnh if hoặc null. Tôi cho rằng tất cả các câu lệnh if có thể được cấu trúc lại thành đối tượng Tùy chọn với một số thao tác trên đó. Tôi có lầm không?

Hãy nhớ một điều – nếu bạn đang sử dụng Tùy chọn và bạn đã viết là quà tặng() hoặc lấy() bạn đã sai và có thể làm điều đó tốt hơn.

Trên đây là toàn bộ thông tin chi tiết nhất về Tùy chọn isPresent () Có hại cho bạn: Mọi điều bạn cần biết. Hướng dẫn này có trả lời câu hỏi của bạn không? Để cho signalfix.net biết trong các ý kiến ​​dưới đây.