In Java 8 and later, the answer to this question is still valid but is now more nuanced.
First, these statements from the accepted answer remain correct:
- interfaces are meant to specify their implicit behaviors in a contract (a statement of rules for behavior that implementing classes must obey in order to be considered valid)
- there is a distinction between the contract (rules) and the implementation (programmatic coding of the rules)
- methods specified in the interface MUST ALWAYS be implemented (at some point)
So, what is the nuance that is new in Java 8? When speaking of "Optional Methods" any of the following are now apt:
1. A method whose implementation is contractually optional
The "third statement" says that abstract interface methods must always be implemented and this remains true in Java 8+. However, as in the Java Collections Framework, it is possible to describe some abstract interface methods as "optional" in the contract.
In this case, the author who is implementing the interface can choose not to implement the method. The compiler will insist upon an implementation, however, and so the author uses this code for any optional methods that are not needed in the particular implementation class:
public SomeReturnType optionalInterfaceMethodA(...) {
throw new UnsupportedOperationException();
}
In Java 7 and earlier, this was really the only kind of "optional method" that there was, i.e. a method that, if not implemented, threw an UnsupportedOperationException. This behavior is necessarily specified by the interface contract (eg. the optional interface methods of the Java Collections Framework).
2. A default method whose re-implementation is optional
Java 8 introduced the concept of default methods. These are methods whose implementation can be and is provided by the interface definition itself. It is generally only possible to provide default methods when the method body can be written using other interface methods (i.e., the "primitives"), and when this
can mean "this object whose class has implemented this interface."
A default method must fulfill the contract of the interface (just like any other interface method implementation must). Therefore, specifying an implementation of the interface method in an implementing class is at the author's discretion (as long as the behavior is suitable to his or her purpose).
In this new environment, the Java Collections Framework could be rewritten as:
public interface List<E> {
:
:
default public boolean add(E element) {
throw new UnsupportedOperationException();
}
:
:
}
In this way, the "optional" method add()
has the default behavior of throwing an UnsupportedOperationException if the implementing class provides no new behavior of its own, which is exactly what you would want to have happen and which is compliant with the contract for List. If an author is writing a class that does not allow new elements to be added to a List implementation, the implementation of add()
is optional because the default behavior is exactly what is needed.
In this case, the "third statement" above still holds true, because the method has been implemented in the interface itself.
3. A method that returns an Optional
result
The final new kind of optional method is simply a method which returns an Optional
. The Optional
class provides a decidedly more object-oriented way of dealing with null
results.
In a fluent style of programming, such as the kind commonly seen when coding with the new Java Streams API, a null result at any point causes the program to crash with a NullPointerException. The Optional
class provides a mechanism for returning null results to client code in a way that enables the fluent style without causing client code to crash.