1. Introduction
In this short tutorial, we’ll be looking at inner interfaces in Java. They are mainly used for:
- solving the namespacing issue when the interface has a common name
- increasing encapsulation
- increasing readability by grouping related interfaces in one place
A well-known example is the Entry interface which is declared inside the Map interface. Defined this way, the interface isn’t in global scope, and it’s referenced as Map.Entry differentiating it from other Entry interfaces and making its relation to Map obvious.
2. Inner Interfaces
By definition, declaration of an inner interface occurs in the body of another interface or class.
They are implicitly public and static as well as their fields when declared in another interface ( similar to field declarations in top-level interfaces), and they can be implemented anywhere:
public interface Customer {
// ...
interface List {
// ...
}
}
Inner interfaces declared within another class are also static, but they can have access specifiers which can constrain where they can be implemented:
public class Customer {
public interface List {
void add(Customer customer);
String getCustomerNames();
}
// ...
}
In the example above, we have a List interface which will serve as declaring some operations on list of Customers such as adding new ones, getting a String representation and so on.
List is a prevalent name, and to work with other libraries defining this interface, we need to separate our declaration, i.e., namespace it.
This is where we make use of an inner interface if we don’t want to go with a new name like CustomerList.
We also kept two related interfaces together which improves encapsulation.
Finally, we can continue with an implementation of it:
public class CommaSeparatedCustomers implements Customer.List {
// ...
}
3. Conclusion
We had a quick look at inner interfaces in Java.
As always, code samples can be found over on GitHub.