There may be times where one may think that I can extend parent class instead of implementing interface. Lets see whats When to choose inheritance over an interface and interface over inheritance.

inheritance over an interface
The main drawback of interfaces is that they are much less flexible than classes when it comes to allowing for the evolution of APIs. Once you ship an interface, the set of its members is fixed forever. Any additions to the interface would break existing types implementing the interface.

A class offers much more flexibility. You can add members to classes that you have already shipped. As long as the method is not abstract (i.e., as long as you provide a default implementation of the method), any existing derived classes continue to function unchanged.

interface over inheritance
Lets take the following code

Mammal.java

public abstract class Animal
{
 public void abstract mate();
 public void abstract feed();
}

Now the above abstract class has two methods mate() and feed().

public class Dog extends Animal
{
}

public class Cat extends Animal
{
}

Now we have Dog and Cat concrete classes extending Animal.

we have few more classes extending Animal

public class Giraffe extends  Animal{}
public class Rhinoceros extends  Animal{}
public class Hippopotamus extends  Animal{}

Now the classes Dog and Cat are pet animals. So it should implement pet behavior. This can be done in two ways.

  1. By defining isPet() method in base class and overriding in child class
  2. By implementing pettable interface.

Now implementing interface is easy compared to overriding method defined in base class because

  1. Interface favours clean code. Defining and Overriding the class may increase code redundancy
  2. Now you get a parakeets which is again a pet and could also fly.If you are inheriting the base class then you need to add canFly() method in base class and set it to return false and override in the parakeets class to return true.

    public class  parakeets extends Animal
    {
      .
      .
        public boolean canFly()
        {
            return true;
        }
    }
    

    Instead you can declare a interface flyable and implement the interface method without making changes to base class

    public class  parakeets extends Animal implements flyable 
    {
      .
      .
        public boolean canFly()
        {
            return true;
        }
    }
    
  3. Interface may be completely not related to class in which it is implemented. Say lets define a carpenter ants class which always moves one after another.Now this can be represented to implement queuing interface which has nothing to do with other animals other then carpenter ants since only ants of this type follows a queue system when they migrate from one place to another

Maven acts as both a dependency management tool – it can be used to retrieve jars from a central repository or from a repository you set up – and as a declarative build tool. The difference between a “declarative” build tool and a more traditional one like ant or make is you configure what needs to get done, not how it gets done. For example, you can say in a maven script that a project should be packaged as a WAR file, and maven knows how to handle that.

Maven relies on conventions about how project directories are laid out in order to achieve its “declarativeness.” For example, it has a convention for where to put your main code, where to put your web.xml, your unit tests, and so on, but also gives the ability to change them if you need to.

Comparable is for objects with a natural ordering. The object itself knows how it is to be ordered.If any class implement Comparable interface in Java then collection of that object either List or Array can be sorted automatically by using Collections.sort() or Arrays.sort() method and object will be sorted based on there natural order defined by CompareTo method.

Comparator is for objects without a natural ordering or when you wish to use a different ordering.

Natural ordering is the Ordering implemented on the objects of each class. This ordering is referred to as the class’s natural ordering.For example Strings Natural Ordering is defined in String Class

Comparable
Compares object of itself with some other objects.Comparable overrides compareTo

Employee.java

package com.acme.users;

public class Employee implements Comparable<Employee> {
	public String EmpName;
	public Integer EmpId;
	public Integer Age;
	
	public Employee(Integer pEmpId, String pEmpName, Integer pAge)
	{
		this.EmpName = pEmpName;
		this.EmpId   = pEmpId;
		this.Age     = pAge;
	}
	
	
	public String getEmpName() {
		return EmpName;
	}
	public void setEmpName(String empName) {
		EmpName = empName;
	}
	public Integer getEmpId() {
		return EmpId;
	}
	public void setEmpId(Integer empId) {
		EmpId = empId;
	}
	public Integer getAge() {
		return Age;
	}
	public void setAge(Integer age) {
		Age = age;
	}
	
	@Override
	public int compareTo(Employee arg0) 
	{	
		if(this.getEmpId() == arg0.getEmpId())
			return 0;
		else if (this.getEmpId() > arg0.getEmpId())
			return 1;
		else
			return -1;
	}
}

EmpDashBoard.java

package com.acme.users;

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

public class EmpDashBoard {
	public static void main(String[] args) {

		List<Employee> arrEmpList = new ArrayList();

		Employee objEmp1 = new Employee(101, "Ahmed", 31);
		Employee objEmp2 = new Employee(127, "Mahesh", 24);
		Employee objEmp3 = new Employee(109, "Viparna", 85);
		Employee objEmp4 = new Employee(101, "Abdul", 26);
		Employee objEmp5 = new Employee(104, "Muthu", 23);
		Employee objEmp6 = new Employee(115, "Monalisa", 25);

		arrEmpList.add(objEmp1);

		arrEmpList.add(objEmp2);
		arrEmpList.add(objEmp3);
		arrEmpList.add(objEmp4);
		arrEmpList.add(objEmp5);
		arrEmpList.add(objEmp6);

		System.out.println("Sorted based on Natural Sorting(Emp Id)");
		System.out.println("Before Sorting");
		dispListContent(arrEmpList);
		
		Collections.sort(arrEmpList);
		
		System.out.println("After Sorting");
		dispListContent(arrEmpList);
	}

	public static void dispListContent(List<Employee> parrEmployeeLst) {
		System.out.println(" ");

		System.out.println("EmpId" + " " + "EmpName" + "     " + "Age");
		System.out.println("---------------------------");
		for (Employee object : parrEmployeeLst) {
			System.out.print(object.getEmpId() + "   ");
			System.out.print(object.getEmpName() + "     ");
			System.out.println(object.getAge() + " ");
		}
	}
}

Output

Sorted based on Natural Sorting(Emp Id)

Before Sorting
 
EmpId EmpName     Age
---------------------------
101   Ahmed       31 
127   Mahesh      24 
109   Viparna     85 
101   Abdul       26 
104   Muthu       23 
115   Monalisa    25 

After Sorting
 
EmpId EmpName     Age
---------------------------
101   Ahmed       31 
101   Abdul       26 
104   Muthu       23 
109   Viparna     85 
115   Monalisa    25 
127   Mahesh      24 

Comparator
In some situations, you may not want to change a class and make it comparable. In such cases, Comparator can be used.Comparator overrides compare

Comparator provides a way for you to provide custom comparison logic for types that you have no control over.

In the below Example I have Sorted the Employee class Objects based on Name(EmpNameComparator), Age(EmpAgeComparator) and based on EmpIDName(EmpIdNameComparator)

EmpDashBoard.java

package com.acme.users;

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

public class EmpDashBoard {
	public static void main(String[] args) {

		List<Employee> arrEmpList = new ArrayList();

		Employee objEmp1 = new Employee(101, "Ahmed", 31);
		Employee objEmp2 = new Employee(127, "Mahesh", 24);
		Employee objEmp3 = new Employee(109, "Viparna", 85);
		Employee objEmp4 = new Employee(101, "Abdul", 26);
		Employee objEmp5 = new Employee(104, "Muthu", 23);
		Employee objEmp6 = new Employee(115, "Monalisa", 25);

		arrEmpList.add(objEmp1);

		arrEmpList.add(objEmp2);
		arrEmpList.add(objEmp3);
		arrEmpList.add(objEmp4);
		arrEmpList.add(objEmp5);
		arrEmpList.add(objEmp6);

		System.out.println("Sorted based on Natural Sorting(Emp Id)");

		System.out.println("Before Sorting");
		dispListContent(arrEmpList);

		System.out.println("Sorting based on Emp Name");
		Collections.sort(arrEmpList, new EmpNameComparator());
		dispListContent(arrEmpList);

		System.out.println("Sorting based on Emp Age");
		Collections.sort(arrEmpList, new EmpAgeComparator());
		dispListContent(arrEmpList);

		System.out.println("Sorting based on EmpId and Name");
		Collections.sort(arrEmpList, new EmpIdNameComparator());
		dispListContent(arrEmpList);
	}

	public static void dispListContent(List<Employee> parrEmployeeLst) {
		System.out.println(" ");

		System.out.println("EmpId" + " " + "EmpName" + "     " + "Age");
		System.out.println("---------------------------");
		for (Employee object : parrEmployeeLst) {
			System.out.print(object.getEmpId() + "   ");
			System.out.print(object.getEmpName() + "     ");
			System.out.println(object.getAge() + " ");
		}
	}
}

EmpNameComparator.java

public class EmpNameComparator implements Comparator<Employee>{

	@Override
	public int compare(Employee o1, Employee o2) {
		String a = o1.getEmpName();
		String b = o2.getEmpName();
		
		//Strings Natural Order Comparable Method
		int compare = a.compareTo(b);
		
		if (compare > 0){
		    return 1;
		}
		else if (compare < 0) {
			return -1;
		}
		else {
			return 0;
		}
	}
}

EmpAgeComparator.java

public class EmpAgeComparator  implements Comparator<Employee> {
	
	@Override
	public int compare(Employee o1, Employee o2) {
		Integer a = o1.getAge();
		Integer b = o2.getAge();
		
		if (a > b){
		    return 1;
		}
		else if (a < b) {
			return -1;
		}
		else {
			return 0;
		}
	}
}

EmpIdNameComparator.java

public class EmpIdNameComparator  implements Comparator<Employee>{
	
	@Override
	public int compare(Employee o1, Employee o2) {
		String a = o1.getEmpName();
		String b = o2.getEmpName();
		
		
		int i = Integer.compare(o1.getEmpId(), o2.getEmpId());
		if (i != 0) return i;

	    return a.compareTo(b);
	}
	
}

Output

Before Sorting
 
EmpId EmpName     Age
---------------------------
101   Ahmed      31 
127   Mahesh     24 
109   Viparna    85 
101   Abdul      26 
104   Muthu      23 
115   Monalisa   25 

Sorting based on Emp Name
 
EmpId EmpName     Age
---------------------------
101   Abdul      26 
101   Ahmed      31 
127   Mahesh     24 
115   Monalisa   25 
104   Muthu      23 
109   Viparna    85 

Sorting based on Emp Age
 
EmpId EmpName     Age
---------------------------
104   Muthu       23 
127   Mahesh      24 
115   Monalisa    25 
101   Abdul       26 
101   Ahmed       31 
109   Viparna     85 

Sorting based on EmpId and Name
 
EmpId EmpName     Age
---------------------------
101   Abdul       26 
101   Ahmed       31 
104   Muthu       23 
109   Viparna     85 
115   Monalisa    25 
127   Mahesh      24 


comparable for natural order, (natural order definition is obviously open to interpretation), and write a comparator for other sorting or comparison needs.

If there is a natural or default way of sorting Object already exist during development of Class than use Comparable. This is intuitive and you given the class name people should be able to guess it correctly like Strings are sorted chronically, Employee can be sorted by there Id etc. On the other hand if an Object can be sorted on multiple ways and client is specifying on which parameter sorting should take place than use Comparator interface. for example Employee can again be sorted on name, salary or department and clients needs an API to do that. Comparator implementation can sort out this problem.

String Questions

  1. How to find the Longest Substring in String
  2. Swapping Letters in 2 Words
  3. Print String in Reverse Order
  4. Print Left Right Angle Triangle
  5. Inverted Right Triangle
  6. Print Right Angle Triangle
  7. Print Pyramid
  8. Sum of Pairs in Array of Numbers
  9. Check 2nd List has all elements in 1st List
  10. How to find String is anagram
  11. Check Palindrome
  12. Reverse of String without for loop and array
  13. Check Palindrome with recursion

1.How to find the Longest Substring in String
Input

String strSample = "ABCAAABCD"

Output

ABCD
public static void main(String[] args) 
{
   String Test = "ABCAAABCD";
   String dummy = ""; 
		
   String[] arrTest = Test.split("");
		
   List<String> seenChars = new ArrayList<String>();
   List<String> subStrings = new ArrayList<String>();
		
   int j = 0;
		
   for (int i = 1; i < arrTest.length; i++) 
   {
      if(seenChars.contains(arrTest[i]))
      {
	 subStrings.add(dummy);
	 dummy = "";
	 seenChars.clear();
      }
			
      seenChars.add(arrTest[i]);
      dummy += arrTest[i];
			
       j = i + 1;
			
       if(j == arrTest.length)
	  subStrings.add(dummy);
   }
		
   int highestNo = 0;
   int lastHighest = 0;
   int currHighestNo = 0;
   int highestPOS = 0;
	
   for(int k = 0; k < subStrings.size() ; k++)
   {
	currHighestNo = subStrings.get(k).length();
		
	if(currHighestNo  > lastHighest)
	{
  	  highestNo = currHighestNo;
	  highestPOS = k;
	}		
	  lastHighest = currHighestNo;
	}
		
	System.out.println(subStrings.get(highestPOS));		
}

Method 2

public static void main(String args[]) 
{
	String Test = "ABCDEAAABCDA";
	String dummy = "";

	String[] arrTest = Test.split("");
	String longestSubString = "";

	List<String> seenChars  = new ArrayList<String>();
	List<String> subStrings = new ArrayList<String>();

	for (String strTest : arrTest) 
	{
		if (seenChars.contains(strTest)) 
		{
			if (dummy.length() > longestSubString.length())
				longestSubString = dummy;

			subStrings.add(dummy);
			dummy = "";
			seenChars.clear();
		}
		
		seenChars.add(strTest);
		dummy += strTest;
	}
	
	if (dummy.length() > longestSubString.length())
	{
		longestSubString = dummy;		
		subStrings.add(dummy);	
	}
	 
	System.out.println("Longest subString is: " + "'" + longestSubString + "'" + " and length is: "
			+ longestSubString.length());
}

2.Swapping Letters in 2 Words
Input

MUGIL XXX

Output

MXUXGXIL
public class Array1 
{
 static List arrNewList1 = new ArrayList();
 
 public static void main(String[] args) 
 { 
   String text1 = "MUGIL";
   String text2 = "XXX"; 
 
   String[] arrList1 = text1.split("");
   String[] arrList2 = text2.split("");
 
   if(arrList2.length > arrList1.length)
    swapArrays(arrList2, arrList1);
   else 
    swapArrays(arrList1, arrList2);

 
 
   StringBuilder strBr = new StringBuilder();
 
   for (int i = 0; i < arrNewList1.size(); i++) 
    strBr.append(arrNewList1.get(i));
 
    System.out.println(strBr); 
 }
 
 public static void swapArrays(String[] pBigList, String[] pSmallList)
 { 
   for (int i = 0; i < pBigList.length; i++) 
   { 
     arrNewList1.add(pBigList[i]);
 
     if(i < pSmallList.length)
      arrNewList1.add(pSmallList[i]);
   }
 }
}

Note

 .
 .
 String Text1 = "M,U,G,I,L";
 String Text2 = "MUGIL";
		
 System.out.println(Text1.split(",").length);
 System.out.println(Text2.split("").length);
 .
 .

Output

5
6

you may be puzzled why first prints 5 and second prints 6.Thats because the empty space between “M is taken as 1 element in Text2

3.Print String in Reverse Order
Input

asanam

Output

asanam
package com.mugil.test;

public class ReverseString {

 public static void main(String[] args) {
  String strName = "manasa";

  //char[] arrNames = strName.toCharArray();

  String[] arrNames = strName.split("");

  for (int i = arrNames.length - 1; i >= 0; i--) {
   System.out.print(arrNames[i]);
  }
 }
}

4.Print Left Right Angle Triangle
Input

Total number of Rows - 5

Output

* 
** 
*** 
**** 
***** 
package com.mugil.test;

public class Patterns2 {
 public static void main(String[] args) {
  int rows = 5;

  for (int i = 1; i <= rows; i++) {
   for (int j = 1; j <= i; j++) {
    System.out.print("*");
   }

   System.out.println(" ");
  }
 }
}

5.Inverted Right Triangle
Input

Total number of Rows - 5

Output

***** 
**** 
*** 
** 
*  
.
int rows = 5;

for (int i = rows; i >= 0; i--) {
 for (int j = 1; j <= i; j++)
  System.out.print("*");

 System.out.println(" ");
}
.

6.Print Right Angle Triangle
Input

Total number of Rows - 5

Output

     * 
    ** 
   *** 
  **** 
 *****  
int n = 5;
int j = 0;
int k = 0;

for (int i = 0; i < n; i++) {
 for (j = n - i; j > 1; j--)
  System.out.print(" ");

 for (j = 0; j <= i; j++)
  System.out.print("*");

 System.out.println();

}

7.Print Pyramid
Input

Total number of Rows - 5

Output

    * 
   * * 
  * * * 
 * * * * 
* * * * *  
int n = 5;
int j = 0;
int k = 0;

for (int i = 0; i < n; i++) 
{
 for (j = n - i; j > 1; j--)
  System.out.print(" ");

 for (j = 0; j <= i; j++)
  System.out.print("* ");

 System.out.println();

}

The only Difference between Right Angle Triangle and Pyramid is Space in *

8.Sum of Number Pairs in Array
Input

Array of Numbers - {0,1,2,2,3,4}
Sum - 4

Output

(0,4)
(1,3)
(2,2)
.
Integer[] arrNumbers = { 0, 1, 2, 2, 3, 4, 5};
int sum = 4;

for (int i = 0; i < arrNumbers.length; i++) {
 for (int j = i + 1; j < arrNumbers.length; j++) {
  if (arrNumbers[i] + arrNumbers[j] == sum) {
   System.out.println("(" + arrNumbers[i] + "," + arrNumbers[j] + ")");
  }
 }
}
.

9.Check 2nd List has all elements in 1st List
Input

2 List of Elements
{1,2,3,4}{2,3}
{1,2,3,4}{2,5}
{2,3}{2,5,6}  
{2,3}{2,3,9}  

Output

{1,2,3,4}{2,3}  -> true
{1,2,3,4}{2,5}  -> false
{2,3}{2,5,6}    -> false
{2,3}{2,3,9}    -> false
public boolean checkEquals()
{
  Integer orig[] = {1,2,3,4};
  Integer act[] = {2,3};
           
  List origList = new ArrayList(Arrays.asList(orig));
  List actList = Arrays.asList(act);
   
  origList.retainAll(actList);
  System.out.println(origList);
      
  if(actList.size()==origList.size())   
    return true;
  else
    return false; 
}

10.How to find String is anagram?
Output

Keep and Peek are anagrams
silent and listen are anagrams
MotherInLaw and HitlerWoman are anagrams
public class AnagramString 
{
 static void isAnagram(String str1, String str2) 
 {
  String s1 = str1.replaceAll("\\s", "");
  String s2 = str2.replaceAll("\\s", "");
  boolean status = true;

  if (s1.length() != s2.length()) 
   status = false;
  else 
  {
   char[] ArrayS1 = s1.toLowerCase().toCharArray();
   char[] ArrayS2 = s2.toLowerCase().toCharArray();
   Arrays.sort(ArrayS1);
   Arrays.sort(ArrayS2);
   status = Arrays.equals(ArrayS1, ArrayS2);
  }

  if (status)
   System.out.println(s1 + " and " + s2 + " are anagrams");
  else
   System.out.println(s1 + " and " + s2 + " are not anagrams");  
 }

 public static void main(String[] args) 
 {
  isAnagram("Keep", "Peek");
  isAnagram("silent", "listen");
  isAnagram("Mother In Law", "Hitler Woman");
 }
}

11.Check Palindrome
Input

malayalam

Output

Entered string is a palindrome
 public static void main(String args[])
 {
      String original, reverse = "";
      original = "madam";
 
      int length = original.length();
 
      for ( int i = length - 1; i >= 0; i-- )
         reverse = reverse + original.charAt(i);
 
      if (original.equals(reverse))
         System.out.println("Entered string is a palindrome.");
      else
         System.out.println("Entered string is not a palindrome."); 
  }

12.Reverse of String without for loop and array
Input

mugil

Output

ligum
static String reverseMe(String s) 
{
   if(s.length() <= 1)
     return s;

   return s.charAt(s.length() - 1) + reverseMe(s.substring(0,s.length()-1));
 }

13.Check palindrome using recursion
Input

malayalam

Output

palindrome

Call the above reverse function and check with string equals method

public static boolean isPalindrome(String input) 
{
 if (input == null)
  return false;

 String reversed = reverse(input);
 return input.equals(reversed);
}

public static String reverse(String str) 
{ 
 if (str == null) 
  return null;
 
 if (str.length() <= 1) 
  return str;
 
 return reverse(str.substring(1)) + str.charAt(0);
}

length – arrays (int[], double[], String[]) —- to know the length of the arrays.

length() – String related Object (String, StringBuilder etc)to know the length of the String

size()– Collection Object (ArrayList, Set etc)to know the size of the Collection

length is not a method, so it completely makes sense that it will not work on objects. Its only works on arrays.

Points to Note

  1. ArrayList allows NULL values many times
  2. Set and HashMap allows NULL once
  3. In HashMap the values will be overwritten when keys are same

List An ordered collection (also known as a sequence). The user of this interface has precise control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.

MapAn object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.

Test.java

public class Test
{
 public static void main(String[] args) 
 {
 List<String> arrNames = new ArrayList<String>();
 
 arrNames.add("Hello");
 arrNames.add(null);
 arrNames.add(null);
 arrNames.add("Hi"); 
 System.out.println("List - "+arrNames.size());
 
 Map hmTest = new HashMap();
 hmTest.put("1", "mugil");
 hmTest.put(null, null);
 hmTest.put(null, null);
 hmTest.put("1", "vannan");
 System.out.println("HashMap - "+ hmTest.size());
 
 Set<Integer> setTest = new HashSet<Integer>();
 
 setTest.add(new Integer("10"));
 setTest.add(new Integer("20"));
 setTest.add(new Integer("10"));
 
 System.out.println("Set - "+ setTest.size());
 }
}

Output

List - 4
HashMap - 2
Set - 2

Why main() method is Static

  1. the main function is where a program starts execution. It is responsible for the high-level organization of the program’s functionality, and typically has access to the command arguments given to the program when it was executed.
  2. main() is static because at that point in the application’s lifecycle, the application stack is procedural in nature due to there being no objects yet instantiated.It’s a clean slate. Your application is running at this point, even without any objects being declared (remember, there’s procedural AND OO coding patterns). You, as the developer, turn the application into an object-oriented solution by creating instances of your objects and depending upon the code compiled within.
  3. static allows main() to be called before an object of the class has been created. This is neccesary because main() is called by the JVM before any objects are made. Since it is static it can be directly invoked via the class.
  4. The method is static because there would be ambiguity: which constructor should be called? Especially if your class looks like this:
    public class JavaClass
    {
      protected JavaClass(int x){}
    
      public void main(String[] args)
      {
      }
    }
    

    If the JVM call new JavaClass(int)? What should it pass for x?

What would be the Output

public class Test 
{
    static
    {
      System.out.println("Hi static 1");        
    }

    public static void main(String[] args) 
    {
        System.out.println("Hi main");
    }

    static
    {
        System.out.println("Hi static 2");        
    }
}

Output

Hi static 1
Hi static 2
Hi main

What happens when you run a class without main() method
Say, file Demo.java contains source code as

public class Demo{ 

}

when this code is compiled as it’s compile successfully as

$javac Demo.java

but when it’s executed as

$java Demo

then it shows an exceptional error

Main method not found in class Demo, please define the main method as: public static void main(String[] args)

so compiler is not responsible to check whether main() method is present or not. JVM is responsible for it. JVM check for main() method with prototype as

public static void main(Strings[] args)

Why JVM search main() method? Is it possible to change main() method into any other method main_hero()?
JVM is instructed to find main() method from inside JVM. Yes, it’s possible to change main() method into main_hero() method but inside JVM you must have to instruct to search main_hero() method.

Why public?
call from anywhere public is used.

Why void?
JVM is going to call main() method but what can JVM do with return value if main() method return.

Can we declare main() method as private or protected or with no access modifier?
No, main() method must be public. You can’t define main() method as private or protected or with no access modifier. This is because to make the main() method accessible to JVM. If you define main() method other than public, compilation will be successful but you will get run time error as no main method found.

Can We Declare main() Method As non-static?
No, main() method must be declared as static so that JVM can call main() method without instantiating it’s class. If you remove ‘static’ from main() method signature, compilation will be successful but program fails at run time.

Most of the Errors incase of change of main() method are runtime errors

Suppose foo is a variable of type long. The following operation is not an atomic operation:

foo = 65465498L;

Indeed, the variable is written using two separate operations: one that writes the first 32 bits, and a second one which writes the last 32 bits. That means that another thread might read the value of foo, and see the intermediate state.

Making the operation atomic consists in using synchronization mechanisms in order to make sure that the operation is seen, from any other thread, as a single, atomic (i.e. not splittable in parts), operation. That means that any other thread, once the operation is made atomic, will either see the value of foo before the assignment, or after the assignment. But never the intermediate value.

A simple way of doing this is to make the variable volatile:

private volatile long foo;

Or to synchronize every access to the variable:

public synchronized void setFoo(long value) {
    this.foo = value;
}

public synchronized long getFoo() {
    return this.foo;
}
// no other use of foo outside of these two methods, unless also synchronized

Stack

  1. The stack is the memory set aside as scratch space for a thread of execution. When a function is called, a block is reserved on the top of the stack for local variables and some bookkeeping data.
  2. When that function returns, the block becomes unused and can be used the next time a function is called. The stack is always reserved in a LIFO (last in first out) order;
  3. the most recently reserved block is always the next block to be freed. This makes it really simple to keep track of the stack; freeing a block from the stack is nothing more than adjusting one pointer.

Heap

  1. The heap is memory set aside for dynamic allocation. Unlike the stack, there’s no enforced pattern to the allocation and deallocation of blocks from the heap;
  2. you can allocate a block at any time and free it at any time. This makes it much more complex to keep track of which parts of the heap are allocated or free at any given time
  3. There are many custom heap allocators available to tune heap performance for different usage patterns.

Each thread gets a stack, while there’s typically only one heap for the application

Which is faster – the stack or the heap? And why?
The stack is much faster than the heap. This is because of the way that memory is allocated on the stack. Allocating memory on the stack is as simple as moving the stack pointer up.

Where are the stack and heap stored?
Both stored in the computer’s RAM (Random Access Memory).

What is stored in stack and heap ?
Stack – Primitives, Calls to methods are stored on the stack
Heap – Class objects including method code and static fields in the heap space.

What determines the size of each of them?
The size of the stack is set when a thread is created. The size of the heap is set on application startup, but can grow as space is needed.

How do the stack and heap work in multithreading?
In a multi-threaded application, each thread will have its own stack. But, all the different threads will share the heap. Because the different threads share the heap in a multi-threaded application, this also means that there has to be some coordination between the threads so that they don’t try to access and manipulate the same piece(s) of memory in the heap at the same time.


How long does memory on the stack last versus memory on the heap?

Once a function call runs to completion, any data on the stack created specifically for that function call will automatically be deleted. Any data on the heap will remain there until it’s manually deleted by the programmer.

Can the stack grow in size? Can the heap grow in size?
The stack is set to a fixed size, and can not grow past it’s fixed size. So, if there is not enough room on the stack to handle the memory being assigned to it, a stack overflow occurs. This often happens when a lot of nested functions are being called, or if there is an infinite recursive call.

If the current size of the heap is too small to accommodate new memory, then more memory can be added to the heap by the operating system. This is one of the big differences between the heap and the stack.

Static methods cannot be overridden but can be redefined in child Class

class Animal 
{
  static void doStuff() 
  {
    System.out.print("animal");
  }
}

class Dog extends Animal 
{
   // it's a redefinition
   // not an override
   static void doStuff() 
   { 					
     System.out.print("dog");
   }

   public static void main(String [] args) 
   {
      Animal [] a = {new Animal(), new Dog(), new Animal()};
     
      for(int x = 0; x < a.length; x++)
     	a[x].doStuff();               // invoke the static method 

    }
}

Output

animal animal animal

Method overriding is made possible by dynamic dispatching, meaning that the declared type of an object doesn’t determine its behavior, but rather its runtime type

Animal lassie = new Dog();
lassie.speak(); // outputs "woof!"
Animal kermit = new Frog();
kermit.speak(); // outputs "ribbit!"

Even though both lassie and kermit are declared as objects of type Animal, their behavior (method .speak()) varies because dynamic dispatching will only bind the method call .speak() to an implementation at run time – not at compile time.

Now, here’s where the static keyword starts to make sense: the word “static” is an antonym for “dynamic”. So the reason why you can’t override static methods is because there is no dynamic dispatching on static members – because static literally means “not dynamic”. If they dispatched dynamically (and thus could be overriden) the static keyword just wouldn’t make sense anymore.