## 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