Showing posts with label interface. Show all posts
Showing posts with label interface. Show all posts

Wednesday, 20 July 2022

When is a class or interface is initialized or loaded in Java?

As per Java language specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1),

 

1. A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

 

a.   T is a class and an instance of T is created.

b.   T is a class and a static method declared by T is invoked.

c.    A static field declared by T is assigned.

d.   A static field declared by T is used and the field is not a constant variable

e.   T is a top level class and an assert statement lexically nested within T is executed.

 

2. A reference to a static field causes initialization of only the class or interface that actually declares it, even though it might be referred to through the name of a subclass, a subinterface, or a class that implements an interface.

 

3. Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization.

 

Let’s experiment the same with below example.

 


A.java

package com.sample.app.dto;

public class A {

	static {
		System.out.println(A.class + " is loaded");
	}
	
	public A() {
		System.out.println(A.class + " constructor is loaded");
	}

}

B.java

package com.sample.app.dto;

public class B{
	
	static {
		System.out.println(B.class + " is loaded");
	}
	
	public static void sayHi() {
		System.out.println("Executing B's sayHi method");
	}
	
	public B() {
		System.out.println(B.class + " constructor is loaded");
	}
	
}

C.java

package com.sample.app.dto;

public class C {

	public static double PI;

	static {
		System.out.println(C.class + " is loaded");
	}

	public C() {
		System.out.println(C.class + " constructor is loaded");
	}
}

D.java

package com.sample.app.dto;

public class D {

	public static double PI = 3.14;

	static {
		System.out.println(D.class + " is loaded");
	}

	public D() {
		System.out.println(D.class + " constructor is loaded");
	}
}

E.java

package com.sample.app.dto;

public class E {
	public static final double PI = 3.14;

	static {
		System.out.println(E.class + " is loaded");
	}

	public E() {
		System.out.println(E.class + " constructor is loaded");
	}
}

F.java

package com.sample.app.dto;

public class F {

	static {
		System.out.println(F.class + " is loaded");
	}

	public F() {
		System.out.println(F.class + " constructor is loaded");
	}
}

App.java

package com.sample.app;

import com.sample.app.dto.A;
import com.sample.app.dto.B;
import com.sample.app.dto.C;
import com.sample.app.dto.D;
import com.sample.app.dto.E;

public class App {
	public static void main(String[] args) throws ClassNotFoundException {

		System.out.println("Getting an instance of the class A");
		A a = new A();
		
		System.out.println("\nCalling B's static method");
		B.sayHi();
		
		System.out.println("\nSetting some value to C's static field");
		C.PI = 3.14;
		
		System.out.println("\nUsing D's static filed");
		System.out.println("D.PI = " + D.PI);
		
		System.out.println("\nUsing E's static filed");
		System.out.println("E.PI = " + E.PI);
		
		System.out.println("\nGet the class object of F");
		Class.forName("com.sample.app.dto.F");
		
	}
}

Output

Getting an instance of the class A
class com.sample.app.dto.A is loaded
class com.sample.app.dto.A constructor is loaded

Calling B's static method
class com.sample.app.dto.B is loaded
Executing B's sayHi method

Setting some value to C's static field
class com.sample.app.dto.C is loaded

Using D's static filed
class com.sample.app.dto.D is loaded
D.PI = 3.14

Using E's static filed
E.PI = 3.14

Get the class object of F
class com.sample.app.dto.F is loaded

In all the dto classes (A.java, B.java etc.,), I used static blocks to demonstrate this application. Static blocks are executed when the class gets loaded by a class loader.

 

Scenario 1: A’s static block is called when I am requesting for an instance of class A.

 

Scenario 2: B’s static block is called, when I am calling B’s static sayHi method.

 

Scenario 3: C’s static block is called when I assign some value if the static variable PI.

 

Scenario 4: D’s static block is called, when I used the D’s static field PI.

 

Scenario 5: Since I am using a constant of the class E, static block is not called here, same is documented in Java specification 1.d.

 

Scenario 6: F’s static block is called, when I am getting Class instance of the class F.

 

References

https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1

https://self-learning-java-tutorial.blogspot.com/2014/02/static-blocks.html



You may like

Interview Questions

Why System.out.println() is not throwing NullPointerException on null references?

Why should we restrict direct access to instance properties?

Closeable vs AutoCloseable in Java

What is the behaviour of static final method in Java?

How to check two double values for equality?

Why to do explicit type casting from double to float conversion?

Saturday, 9 July 2022

Can enum implement an interface in Java?

Enum can implement an interface in Java (Enum can have abstract methods too).

 


Example

enum StringConverters implements Converter<String> {
		LOWER {

			@Override
			public String convert(String str) {
				return str.toLowerCase();
			}

		}
}

 

Find the below working application.

 

EnumImplementInterface.java

package com.sample.app;

public class EnumImplementInterface {

	interface Converter<T> {
		T convert(T data);
	}

	public static enum StringConverters implements Converter<String> {
		LOWER {

			@Override
			public String convert(String str) {
				return str.toLowerCase();
			}

		},
		UPPER {

			@Override
			public String convert(String str) {
				return str.toUpperCase();
			}

		},
		CAMELCASE {

			@Override
			public String convert(String str) {
				return toCamelCase(str);
			}

		};

		private static String toCamelCase(final String str) {
			if (str == null || str.isEmpty())
				return null;

			final StringBuilder builder = new StringBuilder();

			for (final String word : str.split(" ")) {
				if (!word.isEmpty()) {
					builder.append(Character.toUpperCase(word.charAt(0)));
					builder.append(word.substring(1).toLowerCase());
				}
				if (!(builder.length() == str.length()))
					builder.append(" ");
			}

			return builder.toString();
		}
	}

	public static void main(String[] args) {
		String str = "Hi Krishna, how are you";

		System.out.println(StringConverters.LOWER.convert(str));
		System.out.println(StringConverters.UPPER.convert(str));
		System.out.println(StringConverters.CAMELCASE.convert(str));
	}

}

Output

hi krishna, how are you
HI KRISHNA, HOW ARE YOU
Hi Krishna, How Are You



 

 

  

You may like

Interview Questions

How to read the file content using an iterator in Java?

Implement a Closeable iterator in Java

Quick guide to generate random data in Java

What are the different cache eviction strategies?


How to call super class method from sub class overriding method?

Can an enum has abstract methods in Java?

Can an enum has abstract methods in Java?

Enum can have abstract methods in Java. This feature is useful, when you need to provide different implementation for the enum constants.


 

Example

public static enum StringConverters {

	LOWER {

		@Override
		public String convert(String str) {
			return str.toLowerCase();
		}

	},
	CAMELCASE {

		@Override
		public String convert(String str) {
			return toCamelCase(str);
		}

	};

	abstract public String convert(String str);
};

 

Find the below working application.

 

EnumAbstractMethod.java

package com.sample.app;

public class EnumAbstractMethod {

	public static enum StringConverters {

		LOWER {

			@Override
			public String convert(String str) {
				return str.toLowerCase();
			}

		},
		UPPER {

			@Override
			public String convert(String str) {
				return str.toUpperCase();
			}

		},
		CAMELCASE {

			@Override
			public String convert(String str) {
				return toCamelCase(str);
			}

		};

		private static String toCamelCase(final String str) {
			if (str == null || str.isEmpty())
				return null;

			final StringBuilder builder = new StringBuilder();

			for (final String word : str.split(" ")) {
				if (!word.isEmpty()) {
					builder.append(Character.toUpperCase(word.charAt(0)));
					builder.append(word.substring(1).toLowerCase());
				}
				if (!(builder.length() == str.length()))
					builder.append(" ");
			}

			return builder.toString();
		}

		abstract public String convert(String str);
	};

	public static void main(String[] args) {
		String str = "Hi Krishna, how are you";

		System.out.println(StringConverters.LOWER.convert(str));
		System.out.println(StringConverters.UPPER.convert(str));
		System.out.println(StringConverters.CAMELCASE.convert(str));
	}

}

 

Output

hi krishna, how are you
HI KRISHNA, HOW ARE YOU
Hi Krishna, How Are You

 

If you have this kind of use case, you may prefer the enum which implements an interface.

 

EnumImplementInterface.java

package com.sample.app;

public class EnumImplementInterface {

	interface Converter<T> {
		T convert(T data);
	}

	public static enum StringConverters implements Converter<String> {
		LOWER {

			@Override
			public String convert(String str) {
				return str.toLowerCase();
			}

		},
		UPPER {

			@Override
			public String convert(String str) {
				return str.toUpperCase();
			}

		},
		CAMELCASE {

			@Override
			public String convert(String str) {
				return toCamelCase(str);
			}

		};

		private static String toCamelCase(final String str) {
			if (str == null || str.isEmpty())
				return null;

			final StringBuilder builder = new StringBuilder();

			for (final String word : str.split(" ")) {
				if (!word.isEmpty()) {
					builder.append(Character.toUpperCase(word.charAt(0)));
					builder.append(word.substring(1).toLowerCase());
				}
				if (!(builder.length() == str.length()))
					builder.append(" ");
			}

			return builder.toString();
		}
	}

	public static void main(String[] args) {
		String str = "Hi Krishna, how are you";

		System.out.println(StringConverters.LOWER.convert(str));
		System.out.println(StringConverters.UPPER.convert(str));
		System.out.println(StringConverters.CAMELCASE.convert(str));
	}

}

Output

hi krishna, how are you
HI KRISHNA, HOW ARE YOU
Hi Krishna, How Are You




 

 

 

You may like

Interview Questions

Quick guide to race condition in Java with examples

How to read the file content using an iterator in Java?

Implement a Closeable iterator in Java

Quick guide to generate random data in Java

What are the different cache eviction strategies?


How to call super class method from sub class overriding method?

Thursday, 6 January 2022

instanceof operator behavior with interface and class

 Recently I observed a noticeable behavior of instanceof operator while working with interfaces and classes. Let me explain with an example.

InstanceOfDemo.java
public class InstanceOfDemo {

	static interface A{}
	
	static class B{}
	
	static class C{}
	
	public static void main(String args[]) {
		B obj = new B();
		
		System.out.println(obj instanceof A);
		System.out.println(obj instanceof B);
		System.out.println(obj instanceof C);
	}
}

When I try to compile the above program, I end up in compiler error.



It is because Java does not support multiple class inheritance, so it is known during the compilation that an object of type B cannot be a subtype of C. On the other hand, it is possible that obj can be an instance of interface A.

InstanceOfDemo.java
public class InstanceOfDemo {

	static interface A{}
	
	static class B{}
	
	static class C{}
	
	static class D extends B implements A{}
	
	public static void main(String args[]) {
		B obj = new D();
		
		System.out.println(obj instanceof A);
	}
}

In the above snippet, by looking at 'obj instanceof A' expression compiler cannot deduce in advance whether will it evaluate to true or false, but by looking at 'obj instanceof C' compiler knows that this is always evaluated to false, which is meaningless and helps you to prevent an error.




You may like

Interview Questions

Explain Loop inversion in Java

Check whether I have JDK or JRE in my system

How to check whether string contain only whitespaces or not?

How to call base class method from subclass overriding method?

Can an interface extend multiple interfaces in Java?