Java 8 default methods – Basic introduction

Let us assume that you have designed, published a library and you have many clients who use your library. You have followed the “Object Oriented” concepts and hence made use of interfaces, abstract classes, util classes to design your library.

After a few years, you realize that the core library is quite old, they need to move ahead with time and hence you would like to add new features to this library. At the same time you do not want your existing clients knocking at your door at 2:00 am in the morning to complain about a new piece of functionality you added which broke their existing code.

What are the possible solutions to this?

  1. Have a new interface define these methods, introduce an abstract class  to implement the interface and provide some skeletal behavior for the new functionality. This is actually a design technique that has been used in the Collection framework – The problem here is that we have abstract classes which mean that the existing client cannot extend from more than 1 class. 
  2. Classes with static methods – The problem here is that the clients cannot override the functionality if they would like to. This means clients will have to use the single implementation which does not really give them flexibility.

So how do we achieve all of the following?

  1. Add new functionality to an old library.
  2. Not break existing client code.
  3. Allow clients to inherit behavior and not state
  4. Allow clients to override behavior if needed

The answer to this is the default methods. A default method can be directly added to an interface with an implementation. Yes, you read that right! Interfaces with methods and not just the declaration but definition as well.

public interface ExistingInterface {
public void connect();
public void disconnect();
//Default method.
public default void connectUsingNewProtocol(){
System.out.println("Connection to a new device");
}
}

Some examples in the Java library which use the the default method:

1) stream method in the Collection interface – Enables any collection to be streamed.

    default Stream<E> stream() {
        return ...;
    }

2) reversed method in the Comparator interface – Enables reversing of the comparator

    default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }

3) forEach and spliterator in the Iterable interface

One purpose of the default methods was to make changes to the Collection framework without breaking other libraries that use Collection API, like the Apache CollectionUtils or Hibernate and at the same time provide us with new functionality.

We all know that an interface can extend from another interface in Java.  By adding default methods, things get a little complicated and hence there are some things to remember when using default methods:

In the code below, Parent interface has default methods, Child extends from Parent but does not provide implementation.

interface Parent {
default public void methodOne() {
System.out.println("Method one…");
}
default public void methodTwo() {
System.out.println("Method two…");
}
}
interface Child extends Parent{
}
public class ConcreteClass implements Child {
public static void main(String[] args)
{
ConcreteClass concreteClass = new ConcreteClass();
concreteClass.methodOne();
concreteClass.methodTwo();
}
}
}

Output:

Method one…

Method two…

Conclusion : Default methods are inherited in the Child interface.

In the next example below :

Parent interface has default method, Child extends from Parent and does provide or override implementation.

interface Parent
{
default public void methodOne() {
System.out.println("Parent : Method one…");
}
default public void methodTwo() {
System.out.println("Parent : Method two…");
}
}
interface Child extends Parent
{
//overrides methodTwo
default public void methodTwo(){
System.out.println("Child : Method two…");
}
}
public class ConcreteClass implements Child
{
public static void main(String[] args)
{
ConcreteClass concreteClass = new ConcreteClass ();
concreteClass.methodOne();
concreteClass.methodTwo();
}
}

Output:

Parent: Method one…

Child: Method two…

Conclusion:The most specific/ the one at the bottom in the interface hierarchy wins!

What if the ConcreteClass class also provided the implementation for the methodTwo() above ?

public class ConcreteClass implements Child {
public void methodTwo(){
System.out.println("ConcreteClass : Method two…");
}
public static void main(String[] args) {
ConcreteClass concreteClass = new ConcreteClass ();
concreteClass.methodOne();
concreteClass.methodTwo();
}
}

Output:

Parent: Method one…

ConcreteClass: Method two…

Conclusion : Class wins over interface hierarchy!

What happens when we have same default methods in 2 “unrelated” interface and 1 concrete class implementing the 2 interfaces

interface One {
default public void callMe(){
System.out.println("One:callMe…");
}
}
interface Two
{
default public void callMe()
{
System.out.println("Two:callMe…");
}
}
public class ConcreteClass implements One, Two
{
public static void main(String[] args)
{
}
}

Output: The java compiler complains that the method callMe is being inherited from types One and Two. Well, it is our responsibility to resolve the same. This can be done in the following way:

public class ConcreteClass implements One, Two
{
@Override
public void callMe()
{
One.super.callMe();
}
public static void main(String[] args)
{
ConcreteClass concreteClass = new ConcreteClass();
concreteClass.callMe();
}
}

Depending on the implementation of the default method, we can either call the version One or the Two. This is done by using the super keyword. Without using the super keyword, it would mean we are calling the static method on the interface which is not the case here.  At the byte code level , this translates to a invokespecial instruction.

To summarize

  1. Interface hierarchy – the most specific wins
  2. Classes always win in case there is a class that implements a default method and there is an interface hierarchy.
  3. If there is still a problem, it is the responsibility of the developer to resolve it as shown above.

So, does this mean that we do not need abstract classes anymore? Well, that is not right.  What clearly distinguishes the two is state and the fact that a class can inherit only 1 class

So interfaces are always a better idea unless we need state or a skeletal implementation.

Understanding JavaScript hoisting in function declaration and function expression

In my previous blog, I introduced you to one of the main differences between function declaration and function expression in JavaScript. This was called hoisting and we saw that function declaration gets hoisted but function expression does not. This concept of hoisting can be understood as something getting pulled right on top in it’s respective scope. This understanding is good enough at a conceptual level but there is a lot more going on behind the scenes.

Before we embark on the details, an important concept to understand is the execution context of a variable or a function in JavaScript. When a variable is declared inside a function, the execution context for that variable is the function in which it is declared. If it is declared outside, the the execution context is the global context. This is true for functions as well.

The execution context can be either the global code, code inside a function or any eval code. A call to a function results in the formation of a new execution (functional) context.

var taxRatePercentage = 10;       //global context

function calculateTax(amount){    //new execution context - functional context
    var totalTax;

    function deductInsuranceAmount(){   //new execution context when it is called - functional context
        var insuranceAmount;

    }
}

One of the important things to understand here is that the function deductInsuranceAmount can access the totalTax variable but the calculateTax function cannot access the insuranceAmount variable.

There has to be a mechanism through which the JavaScript engine keeps track of the variables, their values and functions in a particular execution context. This is done by maintaining a lexical environment.

So a couple of things are in play here with respect to a execution context:

  1. The lexical environment
  2. The scope chain – The reason why the deductInsuranceAmount function is able to access the totalTax variable defined in the outer/parent function.

Note – To keep it simple and make it easier to comprehend the lexical environment, I am going to leave out the discussion about scope chain in this blog. However the outer reference mentioned in the tables below will give you and idea about the same.

When a function is called, it is this lexical environment that maintains the parameters passed to the function , the variables declared inside the function and the function declarations for a particular execution context.

For the code below :

var taxRatePercentage = 10;       //global context

function calculateTax(amount){    //new execution context
    var totalTax = 0;
    ....
    }
}
calculateTax(20000);

The lexical environment would look like this:

amount20000
totalTax0
outerglobalEnvironment
Simplified Lexical environment for calculateTax function

And the global environment like this:

taxPercentage10
outernull
Simplified environment for the code snippet above.

Internally, the lexical environment actually is split into 2 parts :

  1. The environment record which contains the totalTax, amount declarations as shown above.
  2. The outer link

Two phases of the execution context-

Now with this brief understanding of the lexical environment, let us turn our attention to the execution context. To reiterate, when a function is called, an execution context is created. However there are 2 phases involved with respect to the execution context. The 2 phases are :

  1. When the function is called
  2. When the function is actually executed.

These 2 phases affect the lexical environment. Let us see how.

function calculateTax(amount){    //new execution context
    var totalTax = 0;
    ....
    }
}
calculateTax(20000);

When the calculateTax is called, step 1 above, the execution context is created. Note that our function is not yet being executed. The JavaScript engine creates a lexical environment for this execution context and does the following:

amount20000
totalTaxundefined
outerglobalEnvironment
Simplified Lexical environment during creation phase of the execution context- when function is called but not executed

The parameters passed to the function are initialized with appropriate values but the totalTax variable declared inside remains ‘undefined’ during the creation phase. During phase 2(execution phase), the code is being executed and the environment record is read by the JavaScript engine and then modified as an when necessary.

amount20000
totalTax0
outerglobalEnvironment
Lexical environment when code/function is actually executed.

If we had a function expression inside this function :

function calculateTax(amount){    //new execution context - functional context
    var totalTax = 0;
    calculateInsuranceAmount();
    var calculateInsuranceAmount = function deductInsuranceAmount(){
        ...
    }
}
calculateTax(20000);

The corresponding lexical environment when the function calculateTax is called, during the creation phase would like this :

amount20000
totalTax undefined
calculateInsuranceAmount undefined
outerglobalEnvironment
Lexical environment when function is called but not yet executed.

The code above will result in a error, it will complain that calculateInsuranceAmount is not a function. This is because the function expression is not hoisted, the variable which refers to the function is initialized to undefined during the creation phase of the execution context. During the execution phase, this environment record in the lexical context will be referred to and the error will be thrown.

But if we have a function declaration and the call like this :

sayHello();

function sayHello(){
  console.log('hello');
}

When the sayHello is called, remember the 2 phases. During phase 1, the lexical environment is created but it contains a reference to the actual function in memory in case of function declaration.

sayHelloReference to function sayHello in memory
outerglobalEnvironment
Lexical environment during creation phase when sayHello is called but not executed.

When the code is actually executed, sayHello is present in this lexical environment and it points to the actual function in memory.

If we were to contrast this with function expression :

sayHello();

var sayHello = function(){
  console.log('hello');
}
//Throws 
"error"
"TypeError: sayHello is not a function

This is because, during the creation phase, the lexical environment will look like this:

sayHelloundefined
outerglobalEnvironment
Function expression in lexical environment when the function is called but not executed

This behavior is due the fact that the function expression will be initialized at code execution stage.

This is what happens in case of variables (var) too :

function printToConsole(){
  console.log(x);
  var x = 20;
}

printToConsole();

This results in undefined because during creation phase the variable x has undefined value and during the execution phase, we try to access the value on line 1 above.The lexical environment is looked up and it prints undefined.

So in step 1 : (During context creation phase, the variable is created )

xundefined
outerglobalEnvironment
x in the environment record is undefined during creation phase. The outer environment is the global environment itself.

Step 2 : The code starts executing, tries to access x by referring to the lexical environment and finds it as undefined above.

If we had it like this :

function printToConsole(){
  var x = 20;
  console.log(x);
}

printToConsole();

In Step 1: (During context creation phase, the variable is created )

xundefined
outerglobalEnvironment
Creation phase – The lexical environment for the printToConsole function above.

When the code starts executing , the interpreter executes var x = 20, it looks up at the lexical environment, sees an x there and modifies the value of x to look like the following :

x20
outer globalEnvironment
During execution phase, the variable x is found in the lexical environment and it modifies it to set appropriate value.

Now when the code comes to line 3, it can clearly see the value of 20 assigned to the variable x. This is hoisting from a behind the scenes perspective. This is what happens in case of function declaration, function expression.

Confusion between Lexical and Variable Environment

The specification uses both lexical and variable environment when it addresses the execution context. I have referred to the lexical environment in my explanations above. You can refer to the specification here to get a better understanding of the same. I would also urge you to read an excellent article by Dmitry Soshnikov to get a deeper understanding of the same.

My understanding is that the Lexical Environment was introduced for let,const declarations and for with,catch statements which creates block scope. Another link which explain the difference between the two.

Conclusion

Every function executes in a new execution context. An execution context among other things has a lexical environment which tracks the variables, the values of those variables and the functions. An execution context has 2 phases, creation phase and the execution phase. The lexical environment is created during the creation phase and then modified during execution phase. This gives us a feeling of hoisting of variables and functions declarations.

Further Reading

If you want to take your JavaScript skills to the next level, Toptal has a set of Q&A here to help you get started.

Function declaration vs Function expression in JavaScript

In my previous blog, I introduced you to the basics of function declaration and function expression in JavaScript. In this article, we will answer the following questions:

  1. Why do we need a function expression ?
  2. What is the difference between the two ?

Why do we need a function expression when we have function declaration ?

One of the areas where this can be extremely useful is when you want to pass a function as a parameter to another function and return a function from another function. Let us consider the code below :

function callbackRef(callback) {
  callback();
}


callbackRef(function printHello(){
  console.log('Hello');
});

callbackRef(function printHowdy(){
  console.log('Howdy');
});

The output of the above is Hello Howdy. To break this down, Lines 6 and 10 call the function callbackRef and pass the entire function as a parameter to the function callbackRef. This is accepted by the parameter callback and then we finally execute the function by : callback(). This is the same as function expression where we say :

var callback = function (){

}
callback();

Using function references in the way mentioned above, we can compose and add dynamic behavior. Another use of the function expression is used to create powerful design pattern called the Module Design Pattern which I will explain in another blog.

What is the difference between a function declaration and function expression ?

In JavaScript we can do the following :

printToConsole();

function printToConsole(){
  console.log('hello');
}

To our suprise, the program runs fine and it prints hello even if the function is called before it has been declared. The reason behind this is a concept called hoisting. The English meaning of the word hoisting is something that is raised. Applying this to the function declaration, function declaration is hoisted. What does this mean ?

Mental Model:

//Imagine the function above to be picked up like this :
function printToConsole(){
  console.log('hello');
}
printToConsole();


A simple mental model to understand this is to imagine the function declaration to be hoisted(picked up) in it’s corresponding scope. Now with this understanding, I hope it is clear why the function runs successfully.

Now consider the same example using function expression :

pToC();

var pToC = function printToConsole(){
  console.log('hello');
}

I have used function expression here instead of function declaration. What do you think happens here ? Does it run successfully ?

Well, it does not. It doesn’t run but we also get the following error :

“error”

“ReferenceError: pToC is not defined

In case of function expression , there is no hoisting. As the function expression in not raised up, pToC() throws an error.

Conclusion

The main difference between function declaration and function expression in JavaScript is called hoisting. This difference is more at a conceptual level.

I will dig deeper into this concept of hoisting in my next blog.

Function declaration and Function expression in JavaScript

If you are a backend developer who has never tried JavaScript before, learning JavaScript can be an exhilarating experience but at the same time it can give you a feeling of going  down a rabbit hole. I am going to write a few articles to save a fellow backend developer both time and frustration.

There is a certain vocabulary involved which you should be aware of when you start learning JavaScript.If you are a backend developer wanting to get your hands into JavaScript, there is a good chance that you will get to see a lot of code before you actually starting coding. During this process of learning you will see functions being written in different ways and sometimes this can be a point of confusion.

This article will introduce you to a couple of ways of writing functions in JavaScript.

First way to write a function is:

function calulateTax(amount){
 ...
 return amount * 10;
}

This is called a function declaration. If you are a Java developer, you wouldn’t be too surprised. Keyword function followed by the name of the function, parenthesis to pass any parameters and finally the function body. We need not mention the type of the parameter passed to the function or the type of return value.This function will be executed when you call this function as shown below:

calculateTax(2000);

Second way to write a function is:

var taxCalculation = function(){
   return 20000;
}

This is called a function expression. There is no name(anonymous) given to the function above, it is being referred to by the taxCalculation variable. You could add a name to the function if you wanted.

var calculateTax = function taxCalculator(){
  return 20000;
}

The name of the function, taxCalculator may be useful in stacktraces and inside the function (to call it recursively). To call this function, we need to use the name of the variable :

var taxableAmount = calculateTax();




Third way to write a function :

var calculateTax  = () => return 2000;
var taxableAmount = calculateTax();

or simply

var calculateTax  = () => 2000;  // implicit return as it is single statement
var taxableAmount = calculateTax();

If you are a Java or a .Net developer, this third type should be easy to grasp, this is an arrow function expression in JavaScript.

Conclusion

At a broad level, there are 2 ways of declaring functions in JavaScript : function declaration and function expression. I want to keep this article short and not get into the differences between them.

I will get into the differences between the two in my next blog.