Optional Methods in Java Interface

JavaMethodsInterface

Java Problem Overview


From my understanding if you implement an interface in java, the methods specified in that interface have to be used by the sub classes implementing the said interface.

I've noticed that in some interfaces such as the Collection interface there are methods which are commented as optional, but what exactly does this mean? Its thrown me a bit as I thought all methods specified in the interface would be required?

Java Solutions


Solution 1 - Java

There seems to be an awful lot of confusion in the answers here.

The Java language requires that every method in an interface is implemented by every implementation of that interface. Period. There are no exceptions to this rule. To say "Collections are an exception" suggests a very fuzzy understanding of what's really going on here.

It's important to realize that there are sort of two levels of conforming to an interface:

  1. What the Java language can check. This pretty much just boils down to: is there some implementation for each of the methods?

  2. Actually fulfilling the contract. That is, does the implementation do what the documentation in the interface says it should?

    Well written interfaces will include documentation explaining exactly what is expected from implementations. Your compiler can't check this for you. You need to read the docs, and do what they say. If you don't do what the contract says then you'll have an implementation of the interface as far as the compiler is concerned, but it will be a defective/invalid implementation.

When designing the Collections API Joshua Bloch decided that instead of having very fine-grained interfaces to distinguish between different variants of collections (eg: readable, writable, random-access, etc.) he'd only have very coarse set of interfaces, primarily Collection, List, Set and Map, and then document certain operations as "optional". This was to avoid the combinatorial explosion that would result from fine-grained interfaces. From the Java Collections API Design FAQ:

> To illustrate the problem in gory detail, suppose you want to add the > notion of modifiability to the Hierarchy. You need four new > interfaces: ModifiableCollection, ModifiableSet, ModifiableList, and > ModifiableMap. What was previously a simple hierarchy is now a messy > heterarchy. Also, you need a new Iterator interface for use with > unmodifiable Collections, that does not contain the remove operation. > Now can you do away with UnsupportedOperationException? Unfortunately > not. > > Consider arrays. They implement most of the List operations, but not > remove and add. They are "fixed-size" Lists. If you want to capture > this notion in the hierarchy, you have to add two new interfaces: > VariableSizeList and VariableSizeMap. You don't have to add > VariableSizeCollection and VariableSizeSet, because they'd be > identical to ModifiableCollection and ModifiableSet, but you might > choose to add them anyway for consistency's sake. Also, you need a new > variety of ListIterator that doesn't support the add and remove > operations, to go along with unmodifiable List. Now we're up to ten or > twelve interfaces, plus two new Iterator interfaces, instead of our > original four. Are we done? No. > > Consider logs (such as error logs, audit logs and journals for > recoverable data objects). They are natural append-only sequences, > that support all of the List operations except for remove and set > (replace). They require a new core interface, and a new iterator. > > And what about immutable Collections, as opposed to unmodifiable ones? > (i.e., Collections that cannot be changed by the client AND will never > change for any other reason). Many argue that this is the most > important distinction of all, because it allows multiple threads to > access a collection concurrently without the need for synchronization. > Adding this support to the type hierarchy requires four more > interfaces. > > Now we're up to twenty or so interfaces and five iterators, and it's > almost certain that there are still collections arising in practice > that don't fit cleanly into any of the interfaces. For example, the > collection-views returned by Map are natural delete-only collections. > Also, there are collections that will reject certain elements on the > basis of their value, so we still haven't done away with runtime > exceptions. > > When all was said and done, we felt that it was a sound engineering > compromise to sidestep the whole issue by providing a very small set > of core interfaces that can throw a runtime exception.

When methods in the Collections API are documented as being "optional operations", it does not mean that you can just leave the method implementation out in the implementation, nor does it mean you can use an empty method body (for one thing, many of them need to return a result). Rather, it means that a valid implementation choice (one that still conforms to the contract) is to throw an UnsupportedOperationException.

Note that because UnsupportedOperationException is a RuntimeException you can throw it from any method implementation, as far as the compiler is concerned. For example, you could throw it from an implementation of Collection.size(). However, such an implementation would violate the contract as the documentation for Collection.size() does not say that this is permitted.

Aside: The approach used by Java's Collections API is somewhat controversial (probably less now than when it was first introduced, however). In a perfect world, interfaces would not have optional operations, and fine grained interfaces would instead be used. The problem is that Java supports neither inferred structural types or intersection types, which is why attempting to do things the "right way" ends up becoming extremely unwieldy in the case of collections.

Solution 2 - Java

In order to compile an implementing (non abstract) class for an interface - all methods must be implemented.

However, if we think of a method that its implementation is a simple exception throw as a 'non implemented' (like some methods in the Collection interface), then the Collection interface is the exception in this case, not the regular case. Usually, implementing class should (and will) implement all methods.

The "optional" in collection means that the implementing class doesn't have to 'implement' (according to the terminology above) it, and it will just throw NotSupportedException).

A good example- add() method for immutable collections - the concrete will just implement a method that does nothing but throwing NotSupportedException

In the case of Collection it is done to prevent messy inheritence trees, that will make programmers miserable - but for most cases, this paradigm is not advised, and should be avoided if possible.


Update:

As of java 8, a default method was introduced.

That means, an interface can define a method - including its implementation.
This was added in order to allow adding functionality to interfaces, while still supporting backward compatability for pieces of code that does not need the new functionality.

Note that the method is still implemented by all classes that declare it, but using the interface's definition.

Solution 3 - Java

An interface in Java just declares the contract for implementing classes. All methods in that interface must be implemented, but the implementing classes are free to leave them unimplemented, viz., blank. As a contrived example,

interface Foo {
  void doSomething();
  void doSomethingElse();
}

class MyClass implements Foo {
  public void doSomething() {
     /* All of my code goes here */
  }

  public void doSomethingElse() {
    // I leave this unimplemented
  }
}

Now I have left doSomethingElse() unimplemented, leaving it free for my subclasses to implement. That is optional.

class SubClass extends MyClass {
    @Override
    public void doSomethingElse() {
      // Here's my implementation. 
    }
}

However, if you're talking about Collection interfaces, as others have said, they are an exception. If certain methods are left unimplemented and you call those, they may throw UnsupportedOperationException exceptions.

Solution 4 - Java

The optional methods in the Collection interface mean that the implementation of the method is allowed to throw an exception, but it has to be implemented anyway. As specified in the docs:

> Some collection implementations have restrictions on the elements that > they may contain. For example, some implementations prohibit null > elements, and some have restrictions on the types of their elements. > Attempting to add an ineligible element throws an unchecked exception, > typically NullPointerException or ClassCastException. Attempting to > query the presence of an ineligible element may throw an exception, or > it may simply return false; some implementations will exhibit the > former behavior and some will exhibit the latter. More generally, > attempting an operation on an ineligible element whose completion > would not result in the insertion of an ineligible element into the > collection may throw an exception or it may succeed, at the option of > the implementation. Such exceptions are marked as "optional" in the > specification for this interface.

Solution 5 - Java

All methods have to be implemented for the code to compile, (aside from those with default implementations in Java 8+), but the implementation doesn't have to do anything functionally useful. Specifically, it:

  • May be blank (an empty method.)
  • May just throw an UnsupportedOperationException (or similar)

The latter approach is often taken in the collection classes - all the methods are still implemented, but some may throw an exception if called at runtime.

Solution 6 - Java

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.

Solution 7 - Java

In fact, I am inspired by SurfaceView.Callback2 . I think this is the official way

public class Foo {
    public interface Callback {
        public void requiredMethod1();
        public void requiredMethod2();
    }

    public interface CallbackExtended extends Callback {
        public void optionalMethod1();
        public void optionalMethod2();
    }

    private Callback mCallback;
}

If your class doesnt need to implement optional methods, just "implements Callback". If your class need to implement optional methods, just "implements CallbackExtended".

Sorry for shit English.

Solution 8 - Java

Well, this topic has been adressed to ... yeah .. but think, one answer is missing. Im talking about the "Default Methods" of interfaces. For example, let's imagine you'll have a class for closing anything (like a destructor or something). Let's say it should have 3 methods. Let's call them "doFirst()", "doLast()" and "onClose()".

So we say we want any object of that type to at least realize "onClose()", but the other are optional.

You can realize that, using the "Default Methods" of interfaces. I know, this would most of the Time negate the reason of an interface, but if you are designing an framework, this can be useful.

So if you want to realize it this way, it would look the following

public interface Closer {
    default void doFirst() {
        System.out.print("first ... ");
    }
    void onClose();
    default void doLast() {
        System.out.println("and finally!");
    }
}

What now would happen, if you for example implemented it in an class called "Test", the compiler would be perfectly fine with the following:

public class TestCloser implements Closer {
    @Override
    public void onClose() {
        System.out.print("closing ... ");
    }
}

with the Output:

first ... closing ... and finally!

or

public class TestCloser implements Closer {
    @Override
    public void onClose() {
        System.out.print("closing ... ");
    }

    @Override
    public void doLast() {
        System.out.println("done!");
    }
}

with the output:

first ... closing ... done!

All combinations are possible. Anything with "default" can be implemented, but must not, however anything without must be implemented.

Hope it is not fully wrong that i now answer.

Have a great day everybody!

[edit1]: Please note: This only works in Java 8.

Solution 9 - Java

If we go through the code of AbstractCollection.java in grepCode which is a ancestor class for all collection implementations, it will help us to understand the meaning of optional methods. Here is the code for add(e) method in AbstractCollection class. add(e) method is optional according to collection interface

public boolean  add(E e) {

        throw new UnsupportedOperationException();
    } 

Optional method means it is already implemented in ancestor classes and it throws UnsupportedOperationException upon invocation. If we want to make our collection modifiable then we should override the optional methods in collection interface.

Solution 10 - Java

I was looking for a way to implement the call back interface, so implementing optional methods was necessary since I didn't want to implement every method for each call back.

So, instead of using an interface, I used a class with empty implementation such as:

public class MyCallBack{
    public void didResponseCameBack(String response){}
}

And you can set member variable CallBack like this,

c.setCallBack(new MyCallBack() {
    public void didResponseCameBack(String response) {
        //your implementation here
    }
});

then call it like this.

if(mMyCallBack != null) {
    mMyCallBack.didResponseCameBack(response);
}

This way, you wouldn't need to worry about implementing every methods per call back, but only override the ones you need.

Solution 11 - Java

Although it does not answer the OP's question, it is worth noting that as of Java 8 adding default methods to interfaces is in fact doable. The default keyword placed in an interface's method signature will result in a class having the option to override the method, but not require it to.

Solution 12 - Java

Oracle's Java Collections Tutorial: >To keep the number of core collection interfaces manageable, the Java platform doesn't provide separate interfaces for each variant of each collection type. (Such variants might include immutable, fixed-size, and append-only.) Instead, the modification operations in each interface are designated optional — a given implementation may elect not to support all operations. If an unsupported operation is invoked, a collection throws an UnsupportedOperationException. Implementations are responsible for documenting which of the optional operations they support. All of the Java platform's general-purpose implementations support all of the optional operations.

Solution 13 - Java

I want to make some clarifications with regards to "optional" methods in an interface, keeping in mind that this post is almost 10 years old.

As it has already been mentioned (most notably by @amit), as of Java 8, an interface can have default methods. This is one way you can solve this issue because implementing classes need not to implement a default method (so you could call "optional" from an implementation point of view). However, the fact of the matter is that an implementing class can still call this method because the interface is defining it. So, in reality, it is not an optional behavior because the class already contains the (default) behavior imposed by the interface. I have a better alternative, which I will mention later.

The second point I will make is that implementing a "do nothing" method is a terrible idea the overwhelming majority of the time. "Do nothing" methods introduce side effects that most of the time do more harm than good and potentially, you will never be aware of these side effects. As an example, I would like to use JUnit tests to illustrate this point. If you create a test class with a bunch of "do nothing" test methods, the framework will execute these methods and will mark them as passed when in reality, no tests have been performed. This is a quite dangerous side effect. Extend this scenario to a public library that you might create containing "do nothing" methods. Clients might not be aware of these empty implementations and could call these methods unaware that they do not do anything. I could illustrate more examples, but that is not the point of my answer. All that said, implementing a "do nothing" method is not an example of "optional" behavior. The fact that the method was implemented in the first place, already proves the point that it wasn't optional ("do nothing" behavior is not the same as non-existent behavior).

Regardless of what version of Java you are using, the best solution to this problem is following the "I" in SOLID principles: Interface Segregation Principle. Using ISP, you could segregate optional and required methods in separate interfaces. Supposed you need to create a Calculator and you intend to use a CalculatorOperations interface. But this interface has more operations than you need because your calculator only need to use the four basic math operations (addition, subtraction, multiplication, division). ISP states that no client should be forced to depend on methods it does not use. So, the best way to handle this is by breaking CalculatorOperationsinterface into two or more interfaces; for example, BasicOperations and AdvancedOperations. Once you segregate the required from the optional functions by using different interfaces, you could either have your class implement the required interfaces, or better yet, use Dependency Injection (DI) to inject the required behavior (and even remove it) when needed. For instance, using DI could allow you to show and hide the operations by simply clicking a button (i.e. Windows Calculator).

I know that the calculator operations interface is a trivial example, but the point is that ISP is the best way to make a clear separation between required and optional operations using interfaces in Java.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmjseyView Question on Stackoverflow
Solution 1 - JavaLaurence GonsalvesView Answer on Stackoverflow
Solution 2 - JavaamitView Answer on Stackoverflow
Solution 3 - JavaS.R.IView Answer on Stackoverflow
Solution 4 - JavaMByDView Answer on Stackoverflow
Solution 5 - JavaMichael BerryView Answer on Stackoverflow
Solution 6 - JavascottbView Answer on Stackoverflow
Solution 7 - JavaWonsonView Answer on Stackoverflow
Solution 8 - JavaThorben KuckView Answer on Stackoverflow
Solution 9 - JavaIsAsView Answer on Stackoverflow
Solution 10 - Javagreen0rangeView Answer on Stackoverflow
Solution 11 - JavaTroy StoperaView Answer on Stackoverflow
Solution 12 - JavaTrent SteeleView Answer on Stackoverflow
Solution 13 - JavahfontanezView Answer on Stackoverflow