0% found this document useful (0 votes)
38 views

Concepts to Know Java

Uploaded by

Sabari T
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views

Concepts to Know Java

Uploaded by

Sabari T
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 37

Primitive type Size in memory Range of values

byte 8 bit -128 to 127


short 16 bit to -32768 to 32767
char 16 bit from 0 to 65536
from -2147483648 to
int 32 bits 2147483647
from -
9223372036854775808
to
long 64 bits 9223372036854775807
from (2 to the power -
149) to ((2-2 to the
power -23)*2 to the
float 32 bits power 127)
from (-2 to the power of
63) to ((2 to the power
double 64 bits of 63) - 1)
8 (when used in
arrays), 32 (when
boolean used in non-arrays) true or false
int x = 10;
long y = x; // implicit widening conversion from int to long
System.out.println(y); // Output: 10
Narrowing Conversion:
double a = 10.5;
int b = (int) a; // explicit narrowing conversion from double
to int
System.out.println(b); // Output: 10
Character Conversion:
char c = ‘a’;
int d = (int) c; // explicit conversion from char to int
System.out.println(d); // Output: 97
int e = 97;
char f = (char) e; // explicit conversion from int to char
System.out.println(f); // Output: a
String Conversion:
String str = “123”;
int num = Integer.parseInt(str); // converting string to int
System.out.println(num); // Output: 123
int num2 = 456;
String str2 = Integer.toString(num2); // converting int to
string
System.out.println(str2); // Output: “456”

Primitive to Wrapper Class Conversion:


int g = 123;
Integer gWrapper = Integer.valueOf(g); // converting int to
Integer wrapper class
System.out.println(gWrapper); // Output: 123
Integer hWrapper = new Integer(456);
int h = hWrapper.intValue(); // converting Integer wrapper
class to int
System.out.println(h); // Output: 456

Wrapper Class to Primitive Conversion:


Integer iWrapper = Integer.valueOf(789);
int i = iWrapper.intValue(); // converting Integer wrapper
class to int
System.out.println(i); // Output: 789

Working with hashCode() and equals() methods


in Java
//Something that is important to remember.
//1.Always use the same object attributes to call both and
hashCode()and equals(). Just in our case, we used employee id.
//2.The method equals()must be persistent (if the object has not
changed, the method must return the same value).
//3.Whenever a.equals(b), then a.hashCode()must be the same as
b.hashCode().
//4.If you override one method, you must override the second.

This article shows you a few ways to generate the serialVersionUID for
serialization class.

For Eclipse IDE, move the mouse over the serialization class, or click on
the serialization class and press CTRL + 1.
Puts serialVersionUID=1L; It should be sufficient in most cases.
private static final long serialVersionUID = 1L;

SerialVersionUID is used to ensure that during deserialization /


serialization the same class is loaded.
Serialization at the time of serialization, with every object
sender side JVM will save a Unique Identifier. JVM is
responsible to generate that unique ID based on the
corresponding .class file which is present in the sender system.
Deserialization at the time of deserialization, receiver side JVM
will compare the unique ID associated with the Object with local
class Unique ID i.e. JVM will also create a Unique ID based on the
corresponding .class file which is present in the receiver system.
If both unique ID matched then only deserialization will be
performed. Otherwise, we will get Runtime Exception
saying InvalidClassException . This unique Identifier is nothing
but SerialVersionUID.

To make a request to run the garbage collector, you can call one of the
following methods:
System.gc()
Runtime.getRuntime().gc()

Let's look at an example:


public class TestGC
{
public static void main(String [] args)
{
Object o1 = new Integer(3);
Object o2 = new String("Tutorial");
o1 = o2;
o2 = null;

}
}
Even though o2 is created to refer to null, the object String(string) is not
recyclable since o1 refers to it.

The subclass overrides the method finalize()to free itself from system
resources or for another cleanup:
protected void finalize() throws Throwable
6.Strings in Java
 Java Strings
 Mutable and Immutable String
 String Class Methods
 Command Line Arguments

7. Java Keywords
 Static Variable and Object
 Static Method in Java
 super Keyword in Java
 Java this Keyword
 Java final Keyword
8. Packages in Java
 Java Packages
 Creation of Packages
 Access Specifier
9. Exception Handling
 Java Exception Handling
 Try Catch Block in Java
 NumberFormatException, NullPointerException and
IndexOutofBoundsException
 throw Keyword in Java
 Single try and Multiple Catch
 Multiple try and multiple Catch
 Finally Block in Java
 throws Keyword in Java
0. Java Arrays
 Arrays in Java
 Exception in Array
 For-each Array
 Anonymous Array
 Variable Arguments
11. Multithreading
 Multithreading in Java
 Life cycle of thread
 Methods of thread class
 Constructor of thread class
 Main as a thread
 Creation of thread
 Priority thread
 Daemon thread
 Synchronization
 Runnable Interface
 Wait notify and notifyall methods
12. Wrapper Classes
 Java Wrapper Class
 Parsing in Java
 Boxing and Unboxing in Java
 Character Class in Java
13. Generics in Java
 Generic Classes in Java
 Generic Methods in Java
 Bounded Generics in Java
14. Java Collections
 Collections in Java
 Collection Hierarchy
 Collection Methods
 Methods of List Interface
 Array List in Java
 Linked List in Java
 Vector Class in Java
 Stack in Java
 Set Interface in Java
 Tree Set in Collection
 Cursors in Java
 Maps in Java
 Map Interface Methods
15. Java Input/Output
 I/O in Java
 File Handling in Java
 File Streams
 Serialization in Java
 Deserialization in Java
 Serialization with Inheritance
 Character Stream in Java
 How to design console base login application
16. Java Swing
 Introduction to Java Swing
 GUI application in Java Swing
 Login Application in Swing using NetBeans
17. New Java Concepts
 Java features added after Java 8
 Lambda expression in Multithreading
 Lambda Expression and Functional Interface
 Method Reference
 Method Reference in Multithreading
 Anonymous Class in Java
 Predefined Functional Interface
 Types of Annotation in Java
 Types of Interface in Java
 Sealed Classes and Interfaces
 Record Class
 Text Blocks
18. Projects
 GUI Calculator in Java
 Car Moving Application
 Note Pad in Java
 Tic-Tac-Toe Game in Java
 Java Banking Management System
 Billing System Application in Java

What is the concept of String Pool in Java?

String Pool is a storage area in Java heap.

String allocation, like all object allocation, proves to be a costly affair in both the cases of

time and memory. The JVM performs some steps while initializing string literals to

increase performance and decrease memory overhead. To decrease the number of String

objects created in the JVM, the String class keeps a pool of strings.

Each time a string literal is created, the JVM checks the string literal pool first. If the

string already exists in the string pool, a reference to the pooled instance returns. If the

string does not exist in the pool, a new String object initializes and is placed in the pool.

How Does String pool work in Java?

When you create a new string like this:


String s1 = "Rachel"

JVM automatically checks if the same value exists in the


string constant pool or not.

 if yes, it occupies the already existing value.

 If no, it creates a new string by itself and adds it to


the string pool.

If you want to halt this behavior, create a string using the


new operator:
String s1 = new String("Rachel")

Now, if you are willing to add this string to the string


literal pool, Java provides you with a method called,
intern() method; you can call native intern() method like
this:
S1.intern();

As you know if you’re comparing 2 objects using ==


operator it compares addresses in the memory.

public class StringPoolExperiment


{
public static void main(String[] args)
{
String s1 = "Rachel";
String s2 = "Rachel";
String s3 = new String("Rachel");
String s4 = new String("Rachel").intern();

System.out.println(s1 == s2); // true


System.out.println(s1 == s3); // false
System.out.println(s1 == s4); // true
}
}

Strings CheatSheet:

Creating a String
String in Java is an object that represents a sequence of
char values. A String can be created in two ways:

1. Using a literal

2. Using ‘new’ keyword


String str1 = “Welcome”; // Using literal

String str2 = new String(”Edureka”); // Using new keyword


String Pool
Java String pool refers to a collection of Strings that are
stored in heap memory. In this, whenever a new object is
created, the String pool first checks whether the object is
already present in the pool or not.
String str1 = "abc";
String str2 = "abc";

System.out.println(str1 == str2);
System.out.println(str1 == "abc");

String Conversions

String to Int Conversion


String str="123";
int inum1 = 100;
int inum2 = Integer.parseInt(str);// Converting a string
to int

Int to String Conversion


int var = 111;
String str = String.valueOf(var);
System.out.println(555+str); // Conversion of Int to
String

String to Double conversion


String str = "100.222";
double dnum = Double.parseDouble(str); //displaying the
value of variable dnum

Double to String Conversion


double dnum = 88.9999; //double value
String str = String.valueOf(dnum); //conversion using valueOf()
method

Important Programs

Finding duplicate characters in a String


This program helps you to find out the duplicate
characters in a String.
public void countDupChars(String str)
{
//Create a HashMap
Map<Character, Integer> map = new HashMap<Character,
Integer>();
//Convert the String to char array
char[] chars = str.toCharArray();
for(Character ch:chars){
if(map.containsKey(ch)){
map.put(ch, map.get(ch)+1);
} else {
map.put(ch, 1);
}
}
Set<Character> keys = map.keySet(); //Obtaining set of keys
public static void main(String a[]){
Details obj = new Details();
System.out.println("String: Edureka");
obj.countDupChars("Edureka");
System.out.println("
String: StringCheatSheet");
obj.countDupChars("StringCheatSheet");
}
}

Removing Trailing Spaces of a String

This program tells you how to trim trailing spaces from the
string but not leading spaces.
int len = str.length();
for( ; len > 0; len--)
{
if( ! Character.isWhitespace( str.charAt( len - 1)))
break;
}
return str.substring( 0, len);

StringJoiner Class
StringJoiner mystring = new StringJoiner("-");
// Passing Hyphen(-) as delimiter
mystring.add("edureka");
// Joining multiple strings by using add() method
mystring.add("YouTube");
String reverse using Recursion
class StringReverse
{
/* Function to print reverse of the passed string */
void reverse(String str)
{
if ((str==null)||(str.length() <= 1))
System.out.println(str);
else
{
System.out.print(str.charAt(str.length()-1));
reverse(str.substring(0,str.length()-1));
}
}
/* Driver program to test above function */
public static void main(String[] args){
String str = "Edureka for Java";
StringReverse obj = new StringReverse();
obj.reverse(str);
}
}

Reversing a String entered by a user


String str = "Welcome To Edureka";
String[] strArray = str.split(" ");

for (String temp: strArray)


{
System.out.println(temp);
for(int i=0; i<3; i++)
{
char[] s1 = strArray[i].toCharArray();
for (int j = s1.length-1; j>=0; j--)
{
System.out.print(s1[j]);
}

String Classes & Interfaces

String vs String Buffer


String Buffer vs String Builder

Now, interfaces that are implemented by String,


StringBuffer, and StringBuilder are shown in the below
code.
//String implements all the 3 interfaces
public final class String extends Object
implements Serializable, Comparable<String>, CharSequence

//StringBuffer implements Serializable & CharSequence interfaces


public final class StringBuffer extends Object
implements Serializable, CharSequence

//StringBuilder implements Serializable & CharSequence


interfaces
public final class StringBuilder extends Object
implements Serializable, CharSequence

String vs StringBuffer vs StringBuilder

In the below code, we will perform concatenation


operation with 3 different classes. But, concatenation will
happen only with String Buffer and Builder.
class Edureka{
// Concatenates to String
public static void concat1(String s1)
{
s1 = s1 + "edurekablog";
}
// Concatenates to StringBuilder
public static void concat2(StringBuilder s2)
{
s2.append("edurekablog");
}
// Concatenates to StringBuffer
public static void concat3(StringBuffer s3)
{
s3.append("edurekablog");
}
public static void main(String[] args)
{
String s1 = "Andvideos";
concat1(s1); // s1 is not changed
System.out.println("String: " + s1);
StringBuilder s2 = new StringBuilder("Andvideos");
concat2(s2); // s2 is changed
System.out.println("StringBuilder: " + s2);
StringBuffer s3 = new StringBuffer("Andvideos");
concat3(s3); // s3 is changed
System.out.println("StringBuffer: " + s3);
}
}

Hence, in the output, s1 will remain unchanged and s2 and


s3 will change and concatenation occurs.

String Methods
Few of the most important and frequently used String
methods are listed below:
str1==str2 //compares address;
String newStr = str1.equals(str2); //compares the values
String newStr = str1.equalsIgnoreCase() //compares the values
ignoring the case
newStr = str1.length() //calculates length
newStr = str1.charAt(i) //extract i'th character
newStr = str1.toUpperCase() //returns string in ALL CAPS
newStr = str1.toLowerCase() //returns string in ALL LOWERCASE
newStr = str1.replace(oldVal, newVal) //search and replace
newStr = str1.trim() //trims surrounding whitespace
newStr = str1.contains("value"); //check for the values
newStr = str1.toCharArray(); // convert String to character type
array
newStr = str1.IsEmpty(); //Check for empty String
newStr = str1.endsWith(); //Checks if string ends with the given
suffix

Immutable Strings

In Java, string objects are immutable. Immutable simply


means unmodifiable or unchangeable.
class Stringimmutable{

public static void main(String args[]){

String s="JavaStrings";
s.concat(" CheatSheet");
System.out.println(s);

}
}

The output will be JavaStrings because strings are


immutable and the value will not be changed.

ReflectionAPI (java.lang.reflect package)

Why is Reflection used in Java?


Answer: Using reflection we can inspect classes, interfaces,
constructors, fields, and methods at runtime, even if they are
anonymous at compile time. This inspection allows us to modify
the behavior of these entities at runtime.

Using Reflection API, we can implement the reflection on


the following entities:
 Field: The Field class has information that we use to declare a
variable or a field like a datatype (int, double, String, etc.)
 Method: The Method class can help us to extract information like
access modifier of the method, method return type, method name,
method parameter types, and exception types raised by the
method.
 Constructor: Constructor class gives information about class
constructor that includes constructor access modifier, constructor
name, and parameter types.
 Modifier: Modifier class gives us information about a specific access
modifier. access modifier (private, public, protected, etc.), name
(identifier) and value
 Class :

Method Description
getFields() Returns all the public fields (both for
class & superclass).
getDeclaredFields() Retrieves all the fields of the class.
getModifier() Returns integer representation of
access modifier of the field.
set(classObject, value) Assigns the specified value to the field.
field1.set(s1,"test");
get(classObject) Retrieves field value. (String) field1.get(s1)
setAccessible(boolean) Make private field accessible by
passing true.
getField("fieldName") Returns the field (public) with a
specified field name.
getDeclaredField("field Returns the field with a specified name.
Name")
getType MyFirstClass2.getClass().getDeclaredField("x
").getType() Return Public
Class The getClass() method is used to get the
name of the class to which an object
belongs.
Constructors The getConstructors() method is used to
get the public constructors of the class to
which an object belongs.
Methods The getMethods() method is used to get
the public methods of the class to which
an object belongs.

Reflection: Method
Method Description
getMethods() Retrieves all public methods
defined in the class and its
superclass.
getDeclaredMethod() Returns methods declared in
the class.
getName() Returns the method names.
getModifiers() Returns integer representation
of method’s access modifier.
getReturnType() Returns the method return
type.

Reflection: Constructor
Method Description
getConstructors() Returns all the constructors
declared in class and its
superclass.
getDeclaredConstructor() Returns all the declared
constructors.
getName() Retrieves the name of the
constructor.
getModifiers() Returns the integer
representation of access
modifier of constructors.
getParameterCount() Returns the total number of
parameters for a constructors.

Method 1: invoke(): It invokes a method of the class at runtime


we use the following method.
Syntax:
Method.invoke(Object, parameter)
Ems code:
component.getClass().getMethod("removeContainerListener", parms).invoke(component, parm);

Method 2: Class.getDeclaredField(FieldName): Used to get the


private field. Returns an object of type Field for the specified
field name.
Method 3: Field.setAccessible(true): Allows to access the field
irrespective of the access modifier used with the field.

Student s1 = new Student();

s1.getClass().getInterfaces() -> to get all interfaces

s1.getclass().getPackage() to get package name

import java.lang.reflect.Field; ->


s1.getClass().getFields()/getDeclaredFields()
import java.lang.reflect.Method;->
s1.getClass().getMethods()/getDeclaredMethods()
import java.lang.reflect.Modifier;->
Modifier.toString(field1.getModifiers())

import java.lang.reflect.Constructor->
s1.getClass().getDeclaredConstructors();

 Constructors param count -> getParameterCount()

-> Class[] paramList=c.getParameterTypes();// c is the constructor

Below syntax are same[below example don’t user getClass() method]

Class MyFirstClass6 = Class.forName("myfirstpackage.MyFirstClass");


Class MyFirstClass6 = myfirstpackage.MyFirstClass.class;

System.out.println("MyFirstClass2-get "+MyFirstClass6.getName());
for(Method x : MyFirstClass6.getDeclaredMethods())
System.out.println("MyFirstClass6-get "+x);

Method.invoke example

try {
MyFirstClass MyFirstClass101 = new MyFirstClass();
Method printMessage = MyFirstClass101.getClass().getDeclaredMethod("PrintHello",
String.class, int.class);
printMessage.invoke(MyFirstClass101, "Hello",6);}

catch (InvocationTargetException e)
{
System.out.println(e.getCause());
}
public void PrintHello(String str,int a)
{
System.out.println("string showed:"+str +" value :"+ a);
}
Output :
string showed:Hello value :6

Calling method.invoke in advanced manner -> Object o =


element.getClass().getMethod(method, (Class[]) null).invoke(element,
(Object[]) null);

Using the constructor:


Class cls = Class.forName("myfirstpackage.MyFirstClass");//This is good method used in EMS
Constructor cr = cls.getConstructor(new Class[] {Integer.class, Integer.class,
Integer.class });
Object MyFirstClass2 = (MyFirstClass) cr.newInstance(1, 2, 3 );//This is good method used in
EMS

Field field21 = MyFirstClass2.getClass().getDeclaredField("x");


System.out.println("\nMyFirstClass2-get declared field value :"+ (Integer)
field21.get(MyFirstClass2))


MyFirstClass MyFirstClass1 = new MyFirstClass(4,5,6);//This is good method used in EMS
Field field101 = MyFirstClass1.getClass().getDeclaredField("x");

how to access private method:


Check c = new Check();
Method m = Check.class.getDeclaredMethod("private_Method");
m.setAccessible(true);
m.invoke(c);

How to prevent Singleton Pattern from Reflection, Serialization and


Cloning? - GeeksforGeeks
- // Java program for Enum type singleton
public enum Singleton {
INSTANCE;
}
Overcome serialization issue:- To overcome this issue, we have to
implement the method readResolve() method.

class Singleton implements Serializable {



protected Object readResolve() { return instance; }
….
}

Overcome Cloning issue: To overcome this issue, override clone() method


and throw an exception from clone method that is
CloneNotSupportedException. Now, whenever user will try to create clone
of singleton object, it will throw an exception and hence our class remains
singleton.
class SuperClass implements Cloneable {
int i = 10;
@Override
protected Object clone()
throws CloneNotSupportedException
{
return super.clone();
}
}

drawbacks of Reflection:
 Performance Overhead: Though reflection is a powerful feature,
reflective operations still have slower performance than non-
reflective operations. Hence we should avoid using reflections in
performance-critical applications.
 Security Restrictions: As reflection is a runtime feature, it might
require run-time permissions. So for the applications that require the
code to be executed in a restricted security setting, then reflection
may be of no use.
 Exposure of Internals: By using reflection, we can access private
fields and methods in a class. Thus reflection breaks abstraction that
might render code unportable and dysfunctional.

Dynamic Object Instantiation


public class DynamicInstantiation {
public static void main(String[] args) {
try {
// Dynamically load the class
Class<?> cls = Class.forName("java.util.HashMap");

// Create an instance of the loaded class


Object instance = cls.getDeclaredConstructor().newInstance();
System.out.println("Instance created: " +
instance.getClass().getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}

In this example, Class.forName("java.util.HashMap") loads the HashMap class,


and newInstance() is used to create a new instance of the class at runtime.

Dynamic Class Loading


ServiceLoader<MyService> loader = ServiceLoader.load(MyService.class);
for (MyService service : loader) {
service.doSomething();
}

Example: Spring Framework’s Use of Class.forName()


<!-- Spring XML Configuration Example -->
<bean id="myService" class="com.example.MyService" />

Advantages of Using Class.forName() in Frameworks


 Dependency Injection: Classes can be injected into other components without hardcoding
dependencies.
 Plugin Systems: New features and modules can be added dynamically by loading plugins at
runtime.
 Configuration-Driven Class Loading: Classes can be specified in configuration files,
databases, or external sources, allowing for more adaptable applications.

https://medium.com/@AlexanderObregon/javas-class-forname-method-explained-
8e9f359f1195

Java Annotation: What, Why &


How?
Java Annotations are a way for us to provide Metadata or Additional
Instructions about the Code. Annotations can be used with all Java
Elements like: Class, Interface, Method, Field, etc.

Java Annotations simplify the process of adding additional Info by


providing a solution that takes just 1 extra line of Code, instead of
working with XML Files or Marker Interfaces.

How to use Annotations


Annotations have a straight forward Syntax @annotationName & that's
it.

class User {
@Override
public String toString() {
}
}

public class Main {


public static void main(String[] args) {
@SuppressWarnings("unused")
User u = new User();
}
}

In the code above, we're creating a User class which Overrides the
toString Object Method. We are able to make it much more clear by
adding the @Override Annotation.

In the Main class, we're creating an Instance of User, but we're not using
it. In Oder to bypass the IDE's warnings about unused instance, we're
using the @SuppressWarnings annotation. We're also passing it a String
value unused which makes it clear that we want to ignore the fact that
the Instance is not being used after creation.

But the overriding was pretty clear already & for the warning we can
maybe configure our IDE to ignore certain ones, so, the question arises.

Why do we need Annotations

Annotations are needed to provide additional Info that will be useful for
the Developer, Compiler as well as Run-Time.

Like in the above code @Override does the following:

For the Developer: It makes it clear that the method is being overridden
& it originally belongs to the Superclass.

For the Compiler: It clarifies that the Method is being overridden. Java
Compiler uses this information to verify that the Original Method
Definition or Declaration (in case of Abstract Methods) does exist in the
SuperClass. If not, then we receive a compile time Error. Now this might
not seem like a big deal but consider the following code:

class User {
public String getGreetingString() {
return "Hello";
}
}

class Admin extends User {


@Override
public String getGreetingsString() {
return "Hi!";
}
}

In the code above, we're defining a User Class with a method called
getGreetingString. Then, we're extending it in Admin Class. Admin Class
is Overriding the method & annotating it with @Override.

Most of us might not have even noticed it, but in Admin the method name
has an extra 's' it's defined as getGreetingsString which means it's a
new Method within Admin & not an Overridden Method. Now, such a
mistake would have gone overlooked, but thanks to @Override Annotation
compiler will verify the method Signature & throw an error informing us
that the Method is not Overriding anything because the Method name is
incorrect.

Types of Annotations

As briefly discussed above, Annotations can be useful for the Developer,


Compiler & Run-Time. This categorizes annotations in three types:

1. Source Annotations: These Annotations are only used by the Source Code & the
IDEs to keep the Developer Informed about Certain Details as well as empowering
certain IDE tools. Source Annotations are completely ignored & discarded by the
Compiler & Run-Time. Matter of fact, these annotations don't even reach to the
compiled code or JVM, they are just ignored by compiler & removed at compilation.
Example: @SuppressWarnings.
2. Compiler Annotations: These are used at Compilation to perform certain actions &
to provide info about the Code. These annotations are used by the Compiler, but they
don’t reach the Run-Time. Best example as demonstrated above is @Override.
3. Run-Time Annotations: These annotations are compiled & then used by the Run-
Time. At Run-Time, we can get access to the Annotations Metadata using Reflection
API. This is the type of Annotation mostly used by Frameworks Like, Spring.

Creating Custom Annotations


We can write our own Annotations to be used as we desire.

But before creating an Annotation there are a few questions that need to
be answered, like Can I use @Override for a Class instead of a Method, Or
can I use @FunctionalInterface for a Method or a Field instead of an
Interface. Another set of Questions will be How exactly Annotations are
restricted for Source, Compiler & Run-Time.
For this, we have Annotations that are used on Top of Annotations to
Configure their Behavior.

@Target(ElementType[])

@Target is an annotation that can be used only for Another Annotation


Definition, to define the Target or Code Elements that the Annotation can
be used with. It takes in an Array of ElementType.

ElementType is an enum that defined several Java Types:

 ElementType.TYPE: Class, Interface, Enum, Record & Annotation


 ElementType.FIELD: Fields
 ElementType.METHOD: Method & Constructors
 ElementType.PARAMETER: Method & Constructor Parameters
 ElementType.CONSTRUCTOR: Constructors
 ElementType.LOCAL_VARIABLE: Local Variable
 ElementType.PACKAGE: Package Declarations
 ElementType.ANNOTATION_TYPE: Annotation Type (@Target itself is targeting
this type, that's why we can use it to provide info about Annotations)

@Retention(RetentionPolicy)

@Retention specifies to what level the Annotation & Its data should be
retained in the Code. It takes in a single RetentionPolicy.

RetentionPolicy is an enum defining the Three Retentions:

 RetentionPolicy.SOURCE: This is the default value. This means the Annotation will
be ignored by the Compiler so, obviously, by the Run-Time as well.
 RetentionPolicy.CLASS: Annotation is processed by the Compiler & it retains in the
Class File. It can not be used by the Run-Time.
 RetentionPolicy.RUNTIME: Annotation is processed by the compiler & it's
available to use by the Run-Time using Reflection API.

Creating Our Custom Annotation

We can create an annotation is a Java File using the @interface keyword.

We're going to create an Annotation that Automatically Executes a


Method n number of Times.

import java.lang.annotation.ElementType
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Execute {
int times() default 1;
};

In the code above, we're creating a Custom Annotation called Execute


that takes in an int value referred to as times which defaults to 1.

It can be used with METHODS only as set by @Target.

Its Retention is set to RUNTIME which means we can process it at Run-


Time.

Using Our Custom Annotation

Similar to Built-in ones, Custom annotations work exactly the same.

public class User {


@Execute
public void show() {
System.out.println("Inside Show");
}

@Execute(times = 3)
public void shout() {
System.out.println("Inside Shout");
}
}

In the above code, We're annotating show & shout methods of the User
Class with our Custom @Execute Annotation.

Adding Functionality for Our Custom Annotation

As discussed above, We can access Run-Time Annotations at Run-Time


using Reflection. So, We're going to implement the desired Functionality
as follows:

import java.lang.annotation.Annotation
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {


public static void main(String[] args) {
User u1 = new User();

// Adding functionality for Annotation on Run-Time using Reflection


Class<?> cls = u1.getClass();
for(Method m : cls.getDeclaredMethods()) {
if(m.isAnnotationPresent(Execute.class)) {
Annotation an = m.getAnnotation(Execute.class);
Execute exAn = (Execute) an;
int times = exAn.times();
System.out.println("Executing Method: " + m.getName() + " " +
times + " Time(s)");
for(int i = 1; i <= times; i++) {
try {
m.invoke(u1);
} catch (IllegalAccessException | InvocationTargetException
e) {
e.printStackTrace();
}
}
System.out.println();
}
}
}
};

/* Output:
Inside Shout
Inside Shout
Inside Shout

Inside Show
*/

In the code above, we're getting access to the User's Class Object. Using
that, we're iterating Over User's Declared Methods, checking if the Method
is Annotated with our Custom @Execute Annotation. In which case, we're
invoking the Method number of times as defined by the Annotations Data.

Commonly used Built-In Java Annotations


 @Override | [Target=METHOD | Retention=CLASS]: It indicates that a method
overrides the Superclasses method.
 @SuppressWarnings(String[]) | [Target=TYPE, METHOD, FIELD,
PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE |
Retention=SOURCE]: It Suppresses Warnings as Specified in form of a String[]
passed as value.
 @FunctionalInterface | [Target=TYPE | Retention=RUNTIME]: Declares an
interface as Functional Interface, which means It can only contain One Method
Declaration & can be used with Lambda Expressions. Even if an Interface is not
annotated with @FunctionalInterface if the Interface abides to its rules, Runtime
treats it as FI & allows Lambda Expression. But @FunctionalInterface provides
additional Checks to make sure some doesn't make illegal changes to an FI.
 @Target(ElementType[]) | [Target=ANNOTATION_TYPE |
Retention=RUNTIME]: Specifies the allowed set of ElementTypes that can have the
Annotation.
 @Retention(RetentionPolicy) | [Target=ANNOTATION_TYPE |
Retention=RUNTIME]: Specifies the Retention Policy for an Annotation,
determining its access.

Commonly Used Spring Annotations


 @SpringBootApplication | [Target=TYPE | Retention=RUNTIME]: Indicates the
Main Class of a Spring Boot Application. It combines the functionality of Three
Annotations: @SpringBootConfiguration, @EnableAutoConfiguration &
@ComponentScan which allows Spring to Auto Configure the App & Start
Component Scanning for Bean Creating & Overall Project Analysis.
 @RestController | [Target=TYPE | Retention=RUNTIME]: It defines a RESTful
Web Service Controller. It combines, @Controller & @ResponseBody annotations
so, the class having this annotation is registered as a Controller where each Method
Returns a Response Body.
 @GetMapping | [Target=METHOD | Retention=RUNTIME]: It maps an HTTP
GET Request to a particular method. It combines @RequestMapping allowing us to
specify the Request Parameter, Body, URL Params, Pagination, etc.
 @PostMapping | [Target=METHOD | Retention=RUNTIME]: Same as
@GetMapping, but it Maps HTTP POST Requests.
 @DeleteMapping | [Target=METHOD | Retention=RUNTIME]: Same as
@GetMapping, but it Maps HTTP DELETE Requests.
 @PutMapping | [Target=METHOD | Retention=RUNTIME]: Same as
@GetMapping, but it Maps HTTP PUT Requests.
 @Service | [Target=TYPE | Retention=RUNTIME]: It marks a class as a Service
Component which is used to define the Service Layer of the App, encapsulating
Business Logic.
 @Autowired | [Target=CONSTRUCTOR, METHOD, PARAMETER, FIELD,
ANNOTATION_TYPE | Retention=RUNTIME]: It allows Spring to
Automatically Dependency Inject an Instance based on type.
 @Repository | [Target=TYPE | Retention=RUNTIME]: It marks a Type as a
Repository that will be used for Data Access & for performing Database Operations.
 @Entity | [Target=TYPE | Retention=RUNTIME]: It marks a Type as an Entity
that will be used by Repositories to Map a Database Table to it. The Repositories
retuned data will be of Entity Type & for creation & update as well, it will take in an
argument of Entity Type.
 @PathVariable | [Target=PARAMETER | Retention=RUNTIME]: It will map
the Methods Parameter with a URI Template variable like /products/{:id} here :id is
the Template Variable & it can be accessed in Parameters using
@PathVariable("id") int id.
 @RequestBody | [Target=PARAMETER | Retention=RUNTIME]: It will map
the Methods Parameter with the Request Body.

Here is the source code-


https://github.com/ShivangamSoni/telusko-10-day-challenge/tree/main/day-6/
Annotations/src
1. Getting Started with Spring Data
JPA
3 LESSONS (Text) ~ 1.5 HOURS

1. The Java Persistence Ecosystem


2. Overview of Spring Data JPA (preview lesson)
3. The Persistence Project We’re Building (2 parts)

2. Spring Data Repositories


7 LESSONS (Text) ~ 3.5 HOURS

1. Spring Data JPA Setup


2. Introduction to Spring Data JPA Repositories
3. Derived Query Methods
4. Deep Dive Into Derived Query Methods
5. Spring Data JPA Save Methods
6. Spring Data JPA Delete Methods
7. Testing Spring Data Repositories (preview lesson)

3. Spring Data Custom Queries with JPQL and


native SQL
5 LESSONS (Text) ~ 4 HOURS

1. Using @Query
2. Using @Query with Parameters
3. @Modifying Queries (preview lesson)
4. Named Queries
5. Returning a Custom Object from a Query

4. Pagination and Sorting


5 LESSONS (Text) ~ 4 HOURS

1. Pagination and Sorting Support


2. Sorting
3. Sorting with @Query
4. Pagination (preview lesson)
5. Using Pagination in Controllers (2 parts)

5. Alternate Querying Methods


3 LESSONS (Text) ~ 2 HOURS

1. Building Queries with Specifications


2. Using Query by Example
3. Query DSL

6. Advanced Features
5 LESSONS (Text) ~ 3.5 HOURS

1. Custom Methods in Repositories


2. Spring Data and Transactions
3. Domain Events (preview lesson)
4. Auditing
5. Entity Graphs

Enabling Second-Level Caching


<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId> <version>5.6.15.Final</version>
</dependency>

Microservices :

Step :1 create the service registry as below


spring.application.name=service-registry
http://localhost:8761/

Department service:
In the same url->

spring.application.name=department-service
Right click on the department service project and Run as -> Sprint boot
app
After refreshing the page we can see the eureka service is getting the clients listed as
below.

3.Config server creation

If you could not see the pack in maven then add below things to pom.xml
@EnableConfigServer
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
spring.application.name=config-server

application.yaml
server:
port: 8088

spring:
profiles:
active: native

Got the below issue

Caused by: java.lang.ClassNotFoundException:


org.springframework.web.servlet.config.annotation.WebMvcConfigurer

NoClassDefFoundError: WebMvcConfigurer

Added below lines config-server Pom.xml


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>

jar file checked in this path : (Got it from Maven and placed.)
C:\Users\6114400\.m2\repository\org\springframework\cloud\spring-cloud-config-server\
4.1.3\ spring-cloud-config-server-4.1.3.jar

Now able to connect now.


4) zipkin

First enable the below service.

Got to web site https://hub.docker.com/r/openzipkin/zipkin/#!


Download the docker desktop installer
Logging in Java
Level Value
SEVERE 1000
WARNING 900
INFO 800
CONFIG 700
FINE 500
FINER 400
FINEST 300
OFF Integer.MAX_VALUE - Capturing nothing
ALL Integer.MIN_VALUE - Capturing Everything

o FINEST: It represents the highly detailed tracing message.

o FINER: It represents the detailed tracing message that includes


exceptions thrown by the application, logging details of the method.

o FINE: It represents the most important message out of these.

o CONFIG: It represents the information related to the configuration


of the application. The information may include how much the disk
and memory space. CONFIG messages are intended to provide a variety of static
configuration information, to assist in debugging problems that may be associated with
particular configurations. For example, CONFIG message might include the CPU type, the
graphics depth, the GUI look-and-feel, etc. This level is initialized to 700.

o INFO: The information of the user used by the administrator or


other authorities.

o WARNING: It occurs due to user mistake. If a user inputs the wrong


credentials, the application shows a warning.

o SEVERE: It occurs when some critical or terrible errors shown by


the application. In such cases, the application is not able to continue
further. The popular example of a severe level is out of memory and
unavailability of the database.

private static final Logger LOGGER =


Logger.getLogger(JDBCTransactionBestPractices.class.getName());

LOGGER.info("Transaction committed successfully.");


LOGGER.severe("Transaction rolled back."+ ex.getStackTrace());

logger.setLevel(Level.FINE);

There are two default handlers provided by Java Logging API.

1. ConsoleHandler: This handler writes all the logging messages to console


2. FileHandler: This handler writes all the logging messages to file in the XML
format.

Feature run sync() supplyAsync()


Accepts a Runnable representing a Accepts a Supplier<T> representing a
Input
non-result task result-producing task
CompletableFuture<T> (where T is the
Return Type CompletableFuture<Void>
result type)
Tasks requiring a result for further
Use Case Fire-and-forget tasks without result
processing
Exception No built-in mechanism; exceptions Provides exceptionally() for graceful
Handling propagate to the caller exception handling
Execution Schedule tasks potentially delaying
Instantly launches task
Behavior execution
Chaining Supports thenRun() for subsequent Supports methods like thenApply() for
Operations tasks chaining tasks
May have a slightly better Performance influenced by task
Performance
performance complexity and resources
Background tasks, periodic routines, computational tasks, result-dependent
notifications, running periodic tasks,[fetching data from external
Use Cases
cleanup routines, logging events, or sources, such as databases, APIs, or
triggering notifications remote servers]

Feature runAsync() supplyAsync()

CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {


System.out.println("Task executed asynchronously");
});
future.thenRun(() -> {
// Execute another task after the completion of runAsync()
System.out.println("Another task executed after runAsync()
completes");
});

//output:Task executed asynchronously


//Another task executed after runAsync() completes

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -


>{
return "Result of the asynchronous computation";
});

future.thenApply(result -> {
// Transform the result
return result.toUpperCase();
}).thenAccept(transformedResult -> {
// Consume the transformed result
System.out.println("Transformed Result: " + transformedResult);
});
//output: Transformed Result: RESULT OF THE ASYNCHRONOUS
COMPUTATION

You might also like