## Interface Default and Static Methods In the past, *interfaces* could only have `public abstract` methods. It was not possible to add new functionality to an existing interface unless all inheritors implemented it as well. Additionally it was not possible to create *interface* methods with an implementation. Interfaces can now have `static` and `default` methods ### Static Methods ```java // Static method in an interface interface Vehicle { static String producer() { return "N&F Vehicles"; } } ``` The above `.producer()` function can only be called at the *interface* level. ### Default Methods ```java interface Vehicle { static String producer() { return "N&F Vehicles"; } default String getOverview() { return "ATV made by " + producer(); } } ``` To execute the *default* method, call it from an instance ```java Vehicle vehicle = new VehicleImpl(); String overview = vehicle.getOverview(); ``` --- ## Method References *Method reference* can be used as a shorter, readable alternative to a lambda expression. ### Reference to Static Method Uses the syntax `Class::methodName`. ```java boolean isReal = list.stream().anyMatch(u -> User.isRealUser(u)); ``` vs ```java boolean isReal = list.stream().anyMatch(User::isRealUser); ``` ### Reference to Instance Method Uses the syntax `Instance::methodName`. Let's consider an instance method `.isLegalName(String string)`. ```java // instance method class User { boolean isLegalName(String string) { // implementation } } ``` Then its instance method is called via ```java User user = new User(); boolean isLegalName = list.stream().anyMatch(user::isLegalName) ``` ### Reference to an Instance Method of an Object of a Particular Type ```java long count = list.stream().filter(String::isEmpty).count(); ``` ### Reference to a Constructor ```java Stream<User> stream = list.stream().map(User::new); ``` --- ## Optional\<T\> Before, developers spent a lot of boilerplate writing null checks for returned values. The `Optional<T>` class alleviated this pattern. ### Creation ```java // Empty Optional<String> optional = Optional.empty(); // Non-null values String str = "value"; Optional<String> optional = Optional.of(str); // Return an *Optional* of a specific value or an empty Optional if value is null Optional<String> optional = Optional.ofNullable(getSstring()); ``` ### Usage Case where using `List` ```java // before Java 8 List<String> list = getList(); List<String> listOpt = list != null ? list : new ArrayList<>(); // after Java 8 List<String> list = getList().orElseGet(() -> new ArrayList()); ``` Case where accessing