There are two main naming conventions for interfaces in Java:
suffix for implementations
prefix for interfaces, but no prefix or suffix for implementations.
The latter is popular with folks coming from other languages, such as C#, C++, or Python. Let me show you that in Java ecosystem the former convention is much more powerful than the latter.
One of the main benefits of interface naming conventions is that it helps you coding to the interface not to the implementation (which is a great coding practice).
As an example, let us see the following code excerpt, written in the second convention.
INotifier notifier = myFactory.getNotifier(); // ... Scheduler scheduler = ASingleton.getInstance().getScheduler(); // ... IBrowser browser = loadBrowser();
We can spot that Scheduler has no
prefix. This may raise the concern that we accidently coded to the implementation (and as a consequence call some methods of scheduler varable not present in the interface, forming inflexible code).
However, with this naming convention there may be another obvious reason for the lack of the
prefix: Scheduler may be just a regular class, and no interface was defined.
Let us see how this code looks like when we use the first naming convention:
Notifier notifier = myFactory.getNotifier(); // ... SchedulerImpl scheduler = ASingleton.getInstance().getScheduler(); // ... Browser browser = loadBrowser();
We immediately spot the offensive
suffix, because it is easier to spot what exists (and different) rather than what is missing (
This also leaves no doubt whether Scheduler interface exists. Such
suffix serves as a red herring in Java code, something like a warning in IDE, when it is found in places other than class definitions, factories, or tests. This is the first and the main reason to prefer the first naming convention¹.
The second reason is less, but still important. In C# all the standard library uses
prefix for interfaces, so user classes following the same convention fit naturally.
However, in Java (and its big frameworks like Spring) all interfaces are named without a prefix:
, and not IList;
, not ISerializable;
, not IApplicationContext.
It is just good style to go with naming conventions used by the ecosystem of the language.
Thus, naming is not just a personal style preference; it has real benefits to reduce the number of bugs in the code, and make it more readable within the language ecosystem.
 Nowadays, for local variables types are usually deducted with type inference; however, the principle is still valid for all other usages: fields (class members), and constructor and function parameters.