Annotations in Java provide a means to describe classes, fields, and methods. Essentially, they are a form of metadata added to a Java source file, they can’t affect the semantics of a program directly. However, annotations can be read at run-time using Reflection & this process is known as Introspection. Then it could be used to modify classes, fields, or methods.
This feature is often exploited by Libraries & SDKs (hibernate, JUnit, Spring Framework) to simplify or reduce the amount of code that a programmer would otherwise do in order to work with these Libraries or SDKs. Therefore, it’s fair to say Annotations and Reflection work hand-in hand in Java.
We also get to limit the availability of an annotation to either compile-time or runtime. Below is a simple example on creating a custom annotation
01. Driver.java
package io.hamzeen; import java.lang.annotation.Annotation; public class Driver { public static void main(String[] args) { Class<TestAlpha> obj = TestAlpha.class; if (obj.isAnnotationPresent(IssueInfo.class)) { Annotation annotation = obj.getAnnotation(IssueInfo.class); IssueInfo testerInfo = (IssueInfo) annotation; System.out.printf("%nType: %s", testerInfo.type()); System.out.printf("%nReporter: %s", testerInfo.reporter()); System.out.printf("%nCreated On: %s%n%n", testerInfo.created()); } } }
02. TestAlpha.java
package io.hamzeen; import io.hamzeen.IssueInfo; import io.hamzeen.IssueInfo.Type; @IssueInfo(type = Type.IMPROVEMENT, reporter = "Hamzeen. H.") public class TestAlpha { }
03. IssueInfo.java
package io.hamzeen; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Hamzeen. H. * @created 10/01/2015 * * TestInfo annotation definition */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface IssueInfo { public enum Type { BUG, IMPROVEMENT, FEATURE } Type type() default Type.BUG; String reporter() default "Vimesh"; String created() default "10/01/2015"; }
The Singleton Class Explained
Understand three different ways to define the Singleton class in Java, and why one of them is preferred.
There are a handful of ways to define a Singleton class in Java. They aren’t that difficult, yet doing it the correct way matters. Here I have listed three ways of doing it. However, only the third, which uses an on-demand holder acronym is preferred as the singleton instance created here is thread-safe and unique.
Trivia 1: Why we don’t import classes like System, Integer and String?
Answer: The package java.lang.*;
is implicitly imported.
Trivia 2: Can the main method of a Java program reside in an abstract class?
Answer: Yes it can! See the Driver class below.
1. Eager Singleton
package design.com.hamzeen; public class EagerSingleton { private static EagerSingleton ins = new EagerSingleton(); public static EagerSingleton getInstance() { return ins; } private EagerSingleton() { } }
2. Lazy Singleton
package design.com.hamzeen; public class LazySingleton { private static LazySingleton ins; public static LazySingleton getInstance() { if (ins == null) { ins = new LazySingleton(); } return ins; } private LazySingleton() { } }
3. Singleton Holder
package design.com.hamzeen; public class SingletonHolder { public static SingletonHolder getInstance() { return Holder.ins; } private final static class Holder { private static final SingletonHolder ins = new SingletonHolder(); } private SingletonHolder() { } }
4. The Driver and Output
package design.com.hamzeen; public abstract class Driver { public static void main(String[] args) { EagerSingleton a1 = EagerSingleton.getInstance(); EagerSingleton a2 = EagerSingleton.getInstance(); System.out.println(a1.toString()); System.out.println(a2.toString()); LazySingleton b1 = LazySingleton.getInstance(); LazySingleton b2 = LazySingleton.getInstance(); System.out.println(b1.toString()); System.out.println(b2.toString()); SingletonHolder c1 = SingletonHolder.getInstance(); SingletonHolder c2 = SingletonHolder.getInstance(); System.out.println(c1.toString()); System.out.println(c2.toString()); } }
Courtesy: Dzone