Java OOPs- Inheritance

Inheritance in java is one of the most important concept that is used most extensively in real world applications.

In real world, a web application is made of different layers like front end, seen by user and on which user interacts ,when user sends requests to server, front layer , the one that handles the request and send requests to next layer, business layer, layer which handles all the business logic and dao layer, database layer, all these come into picture.

Every layer has a base class like for example in case of using Spring framework for mvc mechanism , we define a BaseController class , this class has all the basic methods like getting details of logged in user and storing the info in session and many more methods that can be inherited and used by all the other controller classes. A need for inheritance arises when we need some base class having all the generalized methods and fields which a specialized child class can inherit from base class and then add some more specialized methods and fields.

Inheritance in java means, by extending a class , the child class , the one that extends , inherits all the fields and methods of the parent class. Inheritance thus promotes code reusability.

Apart from classes , interfaces can also inherit from their parent interfaces by extending the same.

Lets dive deeper into inheritance

Inheritance with classes

1)In Java, when an “Is-A” relationship exists between two classes we use Inheritance.
2)The parent class is termed super class or base class and the inherited class is the sub class.
3)The keyword “extend” is used by the sub class to inherit the features of super class.

Java only supports single inheritance between classes. This means a class can inherit only from a single class , it cannot extend multiple classes.

A derived class inherits all the public and protected members from the base class, which are not static.In addition, the members with default access are inherited if the child class is in the same package as parent class.

Inheritance and Type Casting

A parent class reference can always refer to and have instance of sub class.
For example, suppose student class extends Parent class.This is referred to as upcasting (from a subclass type to a superclass type).

Student student=new Student();
Person person=student;

The above kind of instances one can find throughout java code as this is also one of the best coding practices . As long as it is possible one should declare variable type as that of Parent class, method arguments should also be declared as parent class variable to make it resuable for different child class.

Example, public void test(List list) , now this list can have instance of either an ArrayList, LinkedList any child class.

It may also be possible to cast an object from a superclass type to a subclass type, but only if the object really is an instance of that subclass (or an instance of a subclass of that subclass). This is referred to as downcasting (from a superclass type to a subclass type).

Student student=new Student();
Person person=student;
Strudent student2=(Student)person;



Today one of my juniors had this doubt whether she should install JRE or JDK on her system so I thought to share the difference on the same.

JRE: Java Runtime Environment , as the name suggests it provides required environment with its java libraries and java virtual machine(JVM) to run java programs. If you only need to run java programs then JRE is the only thing that you need on your system.

However, with JRE you can only run compiled java programs, it cannot compile java programs as it doesnt contain java compiler i.e javac to do the same. If you look into the bin folder of a JRE you wont find any javac.

JDK: Java Development Kit, it is a development kit that contains complete JRE alongwith other java development tools like java compiler i.e javac , a documentation generator i.e javadoc , java debugger. Using JDK, you compile .java files to .class files that contain bytecodes understandable by the JVM.

Internal working of HashMap in java

Basically HashMap is an array of Entry class, a static inner class defined in HashMap is as below:

static class Entry implements Map.Entry {
final K key;
V value;
Entry next;
final int hash;

//getters and setters


Each element in a Hashmap stores in it a key, its value, reference to next entry in case hashvalue is same for two entries in that case a linked list will be formed.

Default initial capacity of a HashMap is 16 i.e a HashMap is initialized with a default 16 sized array.

Now, lets see what happens when we put an element into HashMap.
Following is the code for put method in hashmap:

public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry e = table[i]; e != null; e = {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
return oldValue;

addEntry(hash, key, value, i);
return null;

private V putForNullKey(V value) {
for (Entry e = table[0]; e != null; e = {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
return oldValue;
addEntry(0, null, value, 0);
return null;

Lets decode the above lines of code;
1)As the HashMap allows values to be stored with null keys in the map, firstly we check if key is null or not.
2)If key is null,putForNullKey method is called and null key value is placed at 0th position of array.
for (Entry e = table[0]; e != null; e = {//As each element with same hashvalue forms linked list in a hashmap array, we iterate the element using a for loop.If e==null, we add the new element.

3)If key is not null, we need to find the index in the array where we will store our element and this is done using hashing.
int hash = hash(key.hashCode());//We calculate a unique hash corresponding to each element.

int i = indexFor(hash, table.length);//Passing the hash and array length we find the position in array to store the element.

static int indexFor(int h, int length) {
return h & (length-1);

As you can see we do & operation between array length and hash value and thus a location is found from 1to16, so suppose hash value is 00000000 00010000 & 00000000 00010000, will give an index of 16.

4)Next we check if an element entry exists at above found index if it doesnt exist we add the new element entry but if an entry element already exists at the index position , here comes the linkedlist into the picture.

5)In the if condition if (e.hash == hash && ((k = e.key) == key || key.equals(k))) , we compare the hash value and a comparison with the equals method written for the object or for the same references.

6)If above condition is true, old value is replaced with new value.
7)If 5th condition is false, we iterate the linked list till we find the exact key location and put the entry element.

Implementing two interfaces with same default methods.

In java8 , a new concept is introduced wherein we can provide implementation for methods in an interface using default keyword. But what will happen if a class implements two interfaces with same default methods , which method the implementing class will inherit. Let us see this in the following working example.

I have one interface, TestInterface1 with a default method test()

package com.test;

public interface TestInterface1 {

public default void test() {

An another interface, TestInterface2 too has implementation for method test()

package com.test;

public interface TestInterface2 {

default public void test() {

Now, if I have a class Test that implements above two interfaces , the compiler gives me an error “Duplicate default methods named test with the parameters () and () are inherited from the types TestInterface2 and TestInterface1”

package com.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static*;

import java.lang.reflect.Method;

public class Test implements TestInterface1,TestInterface2{

public static void main(String[] args) {
Test test=new Test();


However, I can remove the above error by providing the compiler which interface method implementation I need in my implementation class.

package com.test;

public class Test implements TestInterface1,TestInterface2{

public static void main(String[] args) {
Test test=new Test();


public void test() {
// TODO Auto-generated method stub
TestInterface1.super.test(); }

So, as shown above in my implementation class method I need to call the method with the interface name whose method implementation I need.

Behaviour of static variable in inheritance

Parent and child instances share a same copy of static variable. This I concluded running the following example.

package com.test;

public class Fruit {

static int count=0;


public static void main(String[] args) {
Chickoo chickoo=new Chickoo();
Fruit fruit=new Fruit();


class Chickoo extends Fruit{

The above code prints value of count as “2” and “3”.

Unexpected results for TreeMap with inconsistent compareTO and equals.

If two objects are considered equal by compareTo() and not by equals() or vice-versa, then TreeSet and TreeMap may produce different output.

public class Employee implements Comparable <<>>
int empNo;
String empName;

public int hashCode() { return empNo; }

public boolean equals(Object obj)
Employee other = (Employee) obj;
if (empNo == other.empNo && empName.equals(other.empName))
return true;
return false;

public int compareTo(Employee other)
return (empNo – other.empNo);

public String toString() { return “[” + empNo + “, ” + empName + “]”; }

public Employee(int empNo, String empName)
this.empNo = empNo;
this.empName = empName;

public static void main(String[] args)
Employee employees[] = new Employee[5];
employees[0] = new Employee(1, “Grima”);
employees[1] = new Employee(2, “Krishma”);
employees[2] = new Employee(2, “Krishma”);
employees[3] = new Employee(4, “Krishma”);
employees[4] = new Employee(2, “Gurav”);

HashSet set = new HashSet();

TreeSet treeSet = new TreeSet();

[[1, Grima], [2, Krishma], [2, Gurav], [4, Krishma]] // HashSet
[[1, Grima], [2, Krishma], [4, Krishma]] //TreeSet

Now as per the “equals” method in Employee two employee objects will be equal if their empNo and empName are equal while “compareTo” method says that two employee objects will be equal if two employee objects have same empNo.

So the output of the hashset is expected, employees with different empNo. and empName are added to set, but if we look at output of TreeSet, employees only with different empNo are added.

Thus we can conclude that TreeMap does not use hashCode() or equals() and it uses the compareTo() method.
This could result in a serious application error where two objects considered equal by equals() return different values from TreeMap.

Summary: All 3 methods – compareTo, equals and hashCode should be consistent with each other.

Java 8 streams filter

package com.test;

import java.util.ArrayList;
import java.util.List;

public class Customer {

private String firstName;

private String lastName;

private int orderNo;

public Customer(String firstName, String lastName, int orderNo) {
this.firstName = firstName;
this.lastName = lastName;
this.orderNo = orderNo;

public String getFirstName() {
return firstName;

public void setFirstName(String firstName) {
this.firstName = firstName;

public String getLastName() {
return lastName;

public void setLastName(String lastName) {
this.lastName = lastName;

public int getOrderNo() {
return orderNo;

public void setOrderNo(int orderNo) {
this.orderNo = orderNo;

public static void main(String[] args) {
List customers=new ArrayList();
customers.add(new Customer(“garima”,”pandey”,1));
customers.add(new Customer(“ashu”,”dikshit”,2));
customers.add(new Customer(“gaurav”,”dixit”,3));

//1)Filter and foreach
//The following basically streams the collection and on a stream you can have multiple operations performed
//The stream has three parts, first is the source which in our case is customers collection, second part is all the operations that need to be performed on that stream, so below is a filter operation that is performed on the stream and finally we have a terminal operation that is the end condition, below for each is the end condition>c.getLastName().startsWith("d")).forEach(c->System.out.println(c.getFirstName()));// output-->ashu,gaurav

//2)Filter and collect
//stream.filter() lets you to filter a list and collect() to convert stream into a list.


//3)filter and .findAny().orElse(null)


//4)filter and .findAny().orElse(null)


//5)filter and map
//map function can be used to perform some operation on all of it’s elements.>c.getFirstName().startsWith("g")).map(Customer::getFirstName).collect(Collectors.toList()).forEach(System.out::println);//output->garima,gaurav


Runtime exception over checked exception in java

When should you create a custom runtime exception??

You can create unchecked exceptions by subclassing RuntimeException whenever your method needs to signal a programming error.

For example there is some method which takes an int argument,performs some operation using that argument and returns. Now it is always a good practice to throw an IllegalArgumentException in the beginning of the method for method arguments that shouldnt be null , so that later you dont have to traverse the method to look what went wrong. Now this exception IllegalArgumentException should be a runtime exception as this is a programming error , user cannot do anything about it and you dont want to write a try catch in every other method where you throw this exception .

Business exceptions should be declared as checked exception as the user can always come out of that exception , like suppose a user tries to book a train ticket and somehow the booking fails in that scenario you wont give user an application error page but will ask to try after some time, such exceptions can be checked exceptions.

Kindly let me know your views on this by posting comments. Thanks 🙂

Hashcode() and equals() for StringBuilder and StringBuffer

StringBuilder and StringBuffer classes doesnt override equals and hashcode() methods in java.

As String class is immutable in java, mutable StringBuilder and StringBuffer were introduced in java to contruct Strings.

equals() and hashcode() method is mainly overridden to support collections so that if i use a map like hashmap i can retrieve my object that i saved using correct key on basis of hashcode() and equals() method.

A key is preferred to be a mutable one so that anytime i can recover my value for that key, now stringbuilder and stringbuffer being mutable are not preferred as keys and hence there is no point of overriding equals() and hashcode() method for them as they shouldnt be used as a candidate for key in collections.

String concatenation in java

String concatenation using + operator::

String sunita="sunita"
String pndey="pandey";
String sunitapandey=sunita+pndey;

Under the covers what does a compiler do:

String sunitapandey=new StringBuilder(String.valueOf(sunita)).append(pndey).toString();

ByteCode for the same—-

0 ldc [16]
2 astore_1 [sunita]
3 ldc [18]
5 astore_2 [pndey]
6 new java.lang.StringBuilder [20]
9 dup
10 aload_1 [sunita]
11 invokestatic java.lang.String.valueOf(java.lang.Object) : java.lang.String [22]
14 invokespecial java.lang.StringBuilder(java.lang.String) [28]
17 aload_2 [pndey]
18 invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [31]
21 invokevirtual java.lang.StringBuilder.toString() : java.lang.String [35]
24 astore_3 [sunitapandey]

//.toString method in Stringbuilder

public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);

the above concatenation will create a new StringBuilder with one char[] buffer with 16 size and at last .toString() method creates a new String object with a copy of StringBuilder buffer.

Suppose you are concatenating using + operator in a loop then imagine the number of temporary objects will be created.

so instead of doing like

String concat="";
for(int i=0;i<100;i++){

one can efficiently do like

StringBuilder concat=new StringBuilder();
String con=concat.toString();

However ,one point to be noted here is , if i use “+” operator for a concatenation and if the result is resolved during compilation time itself then a new StringBuilder instance is not created , stringBuilder conversion is only done for those strings whose value is computed during runtime . Look at following example and their generated bytecode.

String grima="garima"+"pandey";

Bytecode for the same—
0 ldc [16]
2 astore_1 [grima]
3 return
Line numbers:
[pc: 0, line: 8]
[pc: 3, line: 9]
Local variable table:
[pc: 0, pc: 4] local: n index: 0 type: java.lang.String[]
[pc: 3, pc: 4] local: grima index: 1 type: java.lang.String

 Note–Whenever possible prefer .append(char[] str) or .append(char c) methods of StringBuilder over .append(String str) method of StringBuilder as its fast.