1

In most Java code, I see people declare Java objects like this:

Map<String, String> hashMap = new HashMap<>();

instead of:

HashMap<String, String> hashMap = new HashMap<>();

How is it possible (i know it is but why) to create instance of a Map interface when we know that we can't create instance of an interface.Please explain. Thanks in advance.

5

It's called polymorphism:
The instance of a class can be treated as instance of that class but also as an instance of every interface the class implements, since it has to implement all the interface's methods. An interface is a contract that says: "The class implementing me offers at least the same operations that I offer."

Every HashMap is a Map, but not every Map is a HashMap.

  • Well you do get polymorphism from this. You can get polymorphism several different ways. This way is called inheritance. The generic collection just makes it a bit weird. – candied_orange May 28 '17 at 16:45
2

You cannot create an instance of an interface, because an interface is basically an abstract class without the restriction against multiple inheritance.
And an abstract class is missing parts of its implementation, or is explicitly marked as abstract to prohibit instantiation.

What you can do, and in your example did, is instantiating a class derived from (called implementing) said interface, and upcasting it to any base, be it interface, concrete class or abstract class.

Unless the implementer foolishly broke the contract, the Liskov substitution principle applies and it works just like you actually had instantiated the interface.

2

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<>();
  1. A reference variable is declared on the stack with a name 'hashMap' and type Map<String, String>.

  2. A new instance of type HashMap<> is created on the heap

  3. The 'hashMap' variable is assigned a reference handle (i.e. a memory address value) pertaining to the newly-created instance.

Note:

  • 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.

1
Map<String, String> hashMap = new HashMap<>();

The above statement does three things:

  1. Create a new instance of HashMap<String, String>.
  2. Create a variable that can hold a reference to a Map<String, String>.
  3. Store the reference of the object created in step 1 in the variable created in step 2.

It's important to note that underlying object is still a HashMap<String, String>. Since HashMap implements the Map interface, it can be refereed to by a variable with the type Map. In the future, if you needed to change the map implementation, all you need to do is change what is done in step 1.

It's important to note that code that comes after this first line will only have access to methods defined in the Map interface.

For example:

interface SomeInterface {
  void foo();
}
class SomeClass implements SomeInterface {
  void foo() {
    // ...
  }
  void bar() {
    // ...
  }
}
// ...
SomeInterface thing = new SomeClass();
thing.foo(); // works
this.bar(); // doesn't compile because bar() is not defined in SomeInterface

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.