Programs - Java Language

 

Java Language

Programming

  • Private methods are final since we cannot override private methods.
  • When a function is static, runtime polymorphism doesn’t happen.

The answer for the code below is: Base::show() called

	class Base {
		public static void show() {
			System.out.println("Base::show() called");
		}
	}

	class Derived extends Base {
		public static void show() {
			System.out.println("Derived::show() called");
		}
	}

	class Main {
		public static void main(String[] args) {
			Base b = new Derived();
			b.show();
		}
	}
  • It is not allowed to do super.super. We can only access Grandparent’s members using Parent.
  • Every class is part of some package. If no package is specified, will use a special unnamed package.
  • You can import static methods from a class.
// Note static keyword after import.
import static java.lang.System.*;

class StaticImportDemo
{
   public static void main(String args[])
   {      
        out.println("GeeksforGeeks");
   }
}
  • An interface can contain following type of members:
    public, static, final fields (i.e., constants)
    default and static methods with bodies
  • Final method can’t be overridden, Thus, an abstract function can’t be final.
abstract class demo {
  public int a;
  demo() {
    a = 10;
  }
  abstract public void set();
  abstract final public void get(); // final is not allowed here!
}
  • Parameters are passed by value. You cannot write a standard swap method to swap objects.

“Java manipulates objects ‘by reference’, but it passes object references to methods ‘by value’. Means Java copies and passes the reference by value, not the object.”

The output is: i = 10, j = 20, The swap method doesn’t work as expected.

// This swap it not working as the references are passed by value!
public static void swap(Integer i, Integer j) {
	Integer temp = i;
	i = j;
	j = temp;
}

public static void main(String[] args) {
	Integer i = 10;
	Integer j = 20;
	swap(i, j);
	System.out.println("i = " + i + ", j = " + j); // Answer: i = 10, j = 20
}

But you can use a intWrap to swap the values.

class IntWrap {
	int x;
	IntWrap(int x) {
		this.x = x;
	}
}

public class Main {
	public static void main(String[] args) {
		IntWrap i = new IntWrap(10);
		IntWrap j = new IntWrap(20);
		swap(i, j);
		System.out.println("i = " + i.x + ", j = " + j.x);
	}

	public static void swap(IntWrap i, IntWrap j) {
		int temp = i.x;
		i.x = j.x;
		j.x = temp;
	}
}
  • Java doesn’t support default arguments.

This code snippet is wrong:

static int fun(int x = 0) {
  return x;
}
  • Negative numbers are represented by the two’s complement of their absolute value.
class Test {
    public static void main(String args[])  {
       int x = -1; // 11111111111111111111111111111110
       System.out.println(x>>>29); // 7
       System.out.println(x>>>30); // 3
       System.out.println(x>>>31); // 1
   }   
}
  • Consider the associativity when multiple operators applied.
public static void main(String args[])  {
    System.out.println(10  +  20 + "GeeksQuiz");
    System.out.println("GeeksQuiz" + 10 + 20);
}

The result is:

30GeeksQuiz
GeeksQuiz1020
  • array1.equals(array2) is the same as (array1 == array2), just to compare reference value/address. To compare 2 set of arrays, please use Arrays.equals(array1, array2).

  • Unlike class members, local variables of methods must be assigned a value to before they are accessed.

class Main {   
   public static void main(String args[]) {      
         int t;      
         System.out.println(t); // compile error
    }   
}
  • The default constructor calls super() and initializes all instance variables to default value like 0, null.

  • If we write our own constructor, then compiler doesn’t create default constructor in Java.

class Point {
	int m_x, m_y;

	public Point(int x, int y) {
		m_x = x;
		m_y = y;
	}

	public static void main(String args[]) {
		Point p = new Point(); // compile error!
	}
}
  • Static blocks are called before constructors.
public class Test {
	static int a;

	static {
		a = 4;
		System.out.println("inside static block");
		System.out.println("a = " + a);
	}

	Test() {
		System.out.println("inside constructor");
		a = 10;
	}

	public static void func() {
		a = a + 1;
		System.out.println("a = " + a);
	}

	public static void main(String[] args) {
		Test obj = new Test();
		obj.func(); // Alert: The static method should be accessed in a static way.
	}
}

The answer is:

inside static block
a = 4
inside constructor
a = 11
  • Checked vs Unchecked Exceptions

Checked: are the exceptions that are checked at compile time. The method must either handle (catch) or throw the exception.


IOException
FileNotFoundException
ClassNotFoundException

Unchecked: are the exceptions that are not checked at compile time. It’s up to the programers to be civilized, and specify or catch the exceptions.

NullPointerException
ArrayIndexOutOfBoundsException
ArithmeticException
IllegalArgumentException
NumberFormatException

In Java exceptions under Error and RuntimeException classes are unchecked exceptions, everything else under throwable is checked.

  • When a subclass exception is mentioned after base class exception, then error occurs.
class Test {
	public static void main(String[] args) {
		try {
			int a[] = { 1, 2, 3, 4 };
			for (int i = 1; i <= 4; i++) {
				System.out.println("a[" + i + "]=" + a[i] + "\n");
			}
		} catch (Exception e) {
			System.out.println("error = " + e);
		} catch (ArrayIndexOutOfBoundsException e) { // unreachable!
			System.out.println("ArrayIndexOutOfBoundsException");
		}
	}
}

Nested Classes

Java allows to define a class within another class. Such a class is called a nested class.

Nested classes are divided into two categories: static and non-static. Non-static nested classes are called inner classes. Inner classes have access to other members of the enclosing class, even if they are private.

Inner classes have three types: Inner Class, Method-local Inner Class and Anonymous Inner Class.

To create an object for the static nested class:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

To create an inner class, you must first instantiate the outer class. Then create the inner object.

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Garbage Collection

In Java, allocation and de-allocation of memory space for objects are done by the garbage collection process in an automated way by the JVM.

The generational garbage collector is based upon the assumption: “the majority of objects that are created are quickly discarded, and objects that are not quickly collected are likely to be around for a while.”

Hotspot JVM Architecture

Hotspot JVM Architecture

There are three components of the JVM that are focused on when tuning performance. The heap is where your object data is stored. This area is then managed by the garbage collector selected at startup. Most tuning options relate to sizing the heap and choosing the most appropriate garbage collector for your situation. The JIT compiler also has a big impact on performance but rarely requires tuning with the newer versions of the JVM.

To determine which objects are no longer in use, the JVM runs a mark-and-sweep algorithm (DFS). The algorithm traverses all object references, starting with the GC roots, and marks every object found as alive. All of the heap memory that is not occupied by marked objects is reclaimed.

A simple Java application has the following GC roots:

  • Local variable in the main method
  • The main thread
  • Static variables of the main class

GC Roots With Memory Leak

Java Heap Memory

Java Heap Memory is the area of memory used for dynamic allocation. Which is separated into different generations:

Hotspot Heap Structure

  • The Young Generation is where all new objects are allocated and aged. When the young generation fills up, this causes a minor garbage collection. Which is “Stop the World” events!
    1. Eden space
    2. Survivor space (S0 and S1)
  • The Old Generation is used to store long surviving objects. Typically, a threshold is set for young generation object and when that age is met, the object gets moved to the old generation. Eventually the old generation needs to be collected. This event is called a major garbage collection. Which is also “Stop the World” event and much slower, should be minimized.
  • The Permanent Generation contains metadata required by the JVM to describe the classes and methods used in the application. Which is populated by the JVM at runtime based on classes in use by the application. (Removed from Java 8).

Java Garbage Collectors

  • The Serial GC is the default for client style machines. Both minor and major garbage collections are done serially (using a single virtual CPU).

-XX:+UseSerialGC

  • The Parallel GC uses multiple threads to perform GC. It can use multiple CPUs to speed up application throughput. You can specify threads number: -XX:ParallelGCThreads=

-XX:+UseParallelGC // A multi-thread young generation collector -XX:+UseParallelOldGC // Both a multi-thread young and old generation collector

  • The G1 Collector to replace the CMS Collector. The G1 collector is a parallel, concurrent, and incrementally compacting low-pause garbage collector.

-XX:+UseG1GC

With Java 8, the new feature -XX:+UseStringDeduplication can take advantage of the facts that the char arrays are internal to strings and final, so JVM can mess around with them.

Whenever the garbage collector visits String objects it takes note of the char arrays. It takes their hash value and store it alongside with a weak reference to the array. As soon as it finds another String which has the same hash code it compares them char by char.

If they match as well, one String will be modified and point to the char array of the second String. The first char array then is no longer referenced anymore and can be garbage collected.

Monitor JVM Activity

The Visual VM program is included with the JDK and allows developers to monitor various aspects of a running JVM.

The Visual GC plugin for Visual VM provides a graphical representation of the garbage collectors activity in the JVM.

Java Visual GC

Types of References

Strong References

We use daily while writing the code. Any object in the memory which has active strong reference is not eligible for garbage collection. Unless you explicitly make reference pointing to null.

Soft References

The objects which are softly referenced will not be garbaged (even though they are available for garbage collection) until JVM badly needs memory.

That implies even if you make the strong reference pointing to null. The object could be still in memory and you can use soft reference to retrieve it back before cleaned.

Good for Caching implementation.

Weak References

JVM ignores the weak references. They are likely to be garbage collected when JVM runs garbage collector thread.

Phantom References

The objects which are being referenced by phantom references are eligible for garbage collection. But, before removing them from the memory, JVM puts them in a queue called ‘reference queue’.

Calling get() method on phantom reference always returns null.

JavaFX

JavaFX is a software platform for creating and delivering desktop applications, as well as rich internet applications (RIAs) that can run across a wide variety of devices. JavaFX is intended to replace Swing as the standard GUI library for Java SE. JavaFX has support for desktop computers and web browsers on Microsoft Windows, Linux, and macOS.