Java prohibits interfaces being used to create objects, but it does not prohibit them being used to create variables.
Consider what's actually happening in this code:
Map<String, String> hashMap = new HashMap<>();
A reference variable is declared on the stack with a name 'hashMap' and type
new instance of type
HashMap<> is created on the heap
The 'hashMap' variable is assigned a reference handle (i.e. a memory address value) pertaining to the newly-created instance.
- a variable is a named area of memory, on the stack.
- an object is an instance of a class, on the heap.
- a reference variable is a variable for a reference handle.
- a reference handle is a number which represents the memory location of an object on the heap.
This is important because there are two "things" being created in memory, a reference variable and an object. A reference variable is more than just a name for an object; indeed a reference variable can keep a handle on any object, provided that object's type is compatible with the variable's type.
For example, all classes in Java are ultimately derived from
Object, so a variable whose type is
Object can reference any instance of any class.
However, a variable of type
Map<String, String> can only reference an instance of a class which implements the
Map<String, String> interface.
Ultimately, there is no problem with creating a variable from an interface, since reference variables do not support any behaviour in themselves (other than for garbage collection). A reference variable is a way for a program to keep track of the objects allocated on the heap, and the type of a variable determines the operations that the program can perform on a referenced object.