Click if you like the project. Your contributions are heartily welcome.
Multithreading
Collections
Java Database Connectivity (JDBC)
Java Programs
Java String Methods
Jakarta Server Pages (JSP)
Servlets
Java Multiple Choice Questions
Java Design Pattern
Hibernate
Spring Framework Basics
Introduction
Java Architecture
Java Data Types
Java Methods
Java Functional programming
Java Lambda expressions
Java Classes
Java Constructors
Java Array
Java Strings
Java Reflection
Java Streams
Java Regular Expressions
Java File Handling
Java Exceptions
Java Inheritance
Java Method Overriding
Java Polymorphism
Java Abstraction
Java Interfaces
Java Encapsulation
Java Generics
Miscellaneous
Interface methods by default;
Lambda expressions;
Functional interfaces;
References to methods and constructors;
Repeatable annotations
Annotations on data types;
Reflection for method parameters;
Stream API for working with collections;
Parallel sorting of arrays;
New API for working with dates and times;
New JavaScript Nashorn Engine ;
Added several new classes for thread safe operation;
Added a new API for Calendar
and Locale
;
Added support for Unicode 6.2.0 ;
Added a standard class for working with Base64 ;
Added support for unsigned arithmetic;
Improved constructor java.lang.String(byte[], *)
and method performance java.lang.String.getBytes()
;
A new implementation AccessController.doPrivileged
that allows you to set a subset of privileges without having to check all * other access levels;
Password-based algorithms have become more robust;
Added support for SSL / TLS Server Name Indication (NSI) in JSSE Server ;
Improved keystore (KeyStore);
Added SHA-224 algorithm;
Removed JDBC Bridge - ODBC;
PermGen is removed , the method for storing meta-data of classes is changed;
Ability to create profiles for the Java SE platform, which include not the entire platform, but some part of it;
Tools
Added utility jjs
for using JavaScript Nashorn;
The command java
can run JavaFX applications;
Added utility jdeps
for analyzing .class files.
↥ back to top
Nashorn is a JavaScript engine developed in Java by Oracle. Designed to provide the ability to embed JavaScript code in Java applications. Compared to Rhino , which is supported by the Mozilla Foundation, Nashorn provides 2 to 10 times better performance, as it compiles code and transfers bytecode to the Java virtual machine directly in memory. Nashorn can compile JavaScript code and generate Java classes that are loaded with a special loader. It is also possible to call Java code directly from JavaScript.
↥ back to top
jjs
- This is a command line utility that allows you to execute JavaScript programs directly in the console.
↥ back to top
In Java, there are three different ways for reading input from the user in the command line environment ( console ).
1. Using Buffered Reader Class:
This method is used by wrapping the System.in ( standard input stream ) in an InputStreamReader which is wrapped in a BufferedReader, we can read input from the user in the command line.
/** * Buffered Reader Class */import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Test { public static void main(String[] args) throws IOException { // Enter data using BufferReader BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); // Reading data using readLine String name = reader.readLine(); // Printing the read line System.out.println(name); } }
2. Using Scanner Class:
The main purpose of the Scanner class is to parse primitive types and strings using regular expressions, however it is also can be used to read input from the user in the command line.
/** * Scanner Class */import java.util.Scanner;class GetInputFromUser { public static void main(String args[]) { // Using Scanner for Getting Input from User Scanner in = new Scanner(System.in); String s = in.nextLine(); System.out.println("You entered string " + s); int a = in.nextInt(); System.out.println("You entered integer " + a); float b = in.nextFloat(); System.out.println("You entered float " + b); } }
3. Using Console Class:
It has been becoming a preferred way for reading user's input from the command line. In addition, it can be used for reading password-like input without echoing the characters entered by the user; the format string syntax can also be used ( like System.out.printf() ).
/** * Console Class */public class Sample { public static void main(String[] args) { // Using Console to input data from user String name = System.console().readLine(); System.out.println(name); } }
↥ back to top
The javap command displays information about the fields, constructors and methods present in a class file. The javap command ( also known as the Java Disassembler ) disassembles one or more class files.
/** * Java Disassembler */class Simple { public static void main(String args[]) { System.out.println("Hello World"); } }
cmd> javap Simple.class
Output
Compiled from ".java" class Simple { Simple(); public static void main(java.lang.String[]); }
↥ back to top
System.out::println
?The specified expression illustrates passing a reference to a static method of a println()
class System.out
.
↥ back to top
Streams can be sequential and parallel. Operations on sequential streams are performed in one processor thread, on parallel streams - using several processor threads. Parallel streams use the shared stream ForkJoinPool
through the static ForkJoinPool.commonPool()
method. In this case, if the environment is not multi-core, then the stream will be executed as sequential. In fact, the use of parallel streams is reduced to the fact that the data in the streams will be divided into parts, each part is processed on a separate processor core, and in the end these parts are connected, and final operations are performed on them.
You can also use the parallelStream()
interface method to create a parallel stream from the collection Collection
.
To make a regular sequential stream parallel, you must call the Stream
method on the object parallel()
. The method isParallel()
allows you to find out if the stream is parallel.
Using, methods parallel()
and sequential()
it is possible to determine which operations can be parallel, and which only sequential. You can also make a parallel stream from any sequential stream and vice versa:
collection .stream () .peek ( ... ) // operation is sequential .parallel () .map ( ... ) // the operation can be performed in parallel, .sequential () .reduce ( ... ) // operation is sequential again
As a rule, elements are transferred to the stream in the same order in which they are defined in the data source. When working with parallel streams, the system preserves the sequence of elements. An exception is a method forEach()
that can output elements in random order. And in order to maintain the order, it is necessary to apply the method forEachOrdered()
.
Criteria that may affect performance in parallel streams:
Data size - the more data, the more difficult it is to separate the data first, and then combine them.
The number of processor cores. Theoretically, the more cores in a computer, the faster the program will work. If the machine has one core, it makes no sense to use parallel threads.
The simpler the data structure the stream works with, the faster operations will occur. For example, data from is ArrayList
easy to use, since the structure of this collection assumes a sequence of unrelated data. But a type collection LinkedList
is not the best option, since in a sequential list all the elements are connected with previous / next. And such data is difficult to parallelize.
Operations with primitive types will be faster than with class objects.
It is highly recommended that you do not use parallel streams for any long operations (for example, network connections), since all parallel streams work with one ForkJoinPool
, such long operations can stop all parallel streams in the JVM due to the lack of available threads in the pool, etc. e. parallel streams should be used only for short operations where the count goes for milliseconds, but not for those where the count can go for seconds and minutes;
Saving order in parallel streams increases execution costs, and if order is not important, it is possible to disable its saving and thereby increase productivity by using an intermediate operation unordered()
:
collection.parallelStream () .sorted () .unordered () .collect ( Collectors . toList ());
↥ back to top
Java Virtual Machine (JVM) is a specification that provides runtime environment in which java bytecode(.class files) can be executed. The JVM is the platform. The JVM acts as a "virtual" machine or processor. Java's platform independence consists mostly of its Java Virtual Machine (JVM). JVM makes this possible because it is aware of the specific instruction lengths and other particularities of the platform (Operating System).
The JVM is not platform independent. Java Virtual Machine (JVM) provides the environment to execute the java file(. Class file). So at the end it's depends on kernel and kernel is differ from OS (Operating System) to OS. The JVM is used to both translate the bytecode into the machine language for a particular computer and actually execute the corresponding machine-language instructions as well.
↥ back to top
The Just-In-Time (JIT) compiler is a component of the runtime environment that improves the performance of Java applications by compiling bytecodes to native machine code at run time.
Java programs consists of classes, which contain platform-neutral bytecodes that can be interpreted by a JVM on many different computer architectures. At run time, the JVM loads the class files, determines the semantics of each individual bytecode, and performs the appropriate computation. The additional processor and memory usage during interpretation means that a Java application performs more slowly than a native application. The JIT compiler helps improve the performance of Java programs by compiling bytecodes into native machine code at run time. The JIT compiler is enabled by default. When a method has been compiled, the JVM calls the compiled code of that method directly instead of interpreting it.
↥ back to top
The Java ClassLoader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine. Java code is compiled into class file by javac compiler and JVM executes Java program, by executing byte codes written in class file. ClassLoader is responsible for loading class files from file system, network or any other source.
Types of ClassLoader:
1. Bootstrap Class Loader:
It loads standard JDK class files from rt.jar and other core classes. It loads class files from jre/lib/rt.jar. For example, java.lang package class.
2. Extensions Class Loader:
It loads classes from the JDK extensions directly usually JAVA_HOME/lib/ext
directory or any other directory as java.ext.dirs.
3. System Class Loader:
It loads application specific classes from the CLASSPATH environment variable. It can be set while invoking program using -cp or classpath command line options.
↥ back to top
1. JDK:
Java Development Kit is the core component of Java Environment and provides all the tools, executables and binaries required to compile, debug and execute a Java Program.
2. JVM:
JVM is responsible for converting Byte code to the machine specific code. JVM is also platform dependent and provides core java functions like memory management, garbage collection, security etc. JVM is customizable and we can use java options to customize it, for example allocating minimum and maximum memory to JVM. JVM is called virtual because it provides an interface that does not depend on the underlying operating system and machine hardware.
2. JRE:
Java Runtime Environment provides a platform to execute java programs. JRE consists of JVM and java binaries and other classes to execute any program successfully.
↥ back to top
1. Java Heap Space:
Java Heap space is used by java runtime to allocate memory to Objects and JRE classes. Whenever we create any object, it's always created in the Heap space.
Garbage Collection runs on the heap memory to free the memory used by objects that doesn't have any reference. Any object created in the heap space has global access and can be referenced from anywhere of the application.
2. Java Stack Memory:
Stack in java is a section of memory which contains methods, local variables and reference variables. Local variables are created in the stack.
Stack memory is always referenced in LIFO ( Last-In-First-Out ) order. Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to other objects in the method.
As soon as method ends, the block becomes unused and become available for next method. Stack memory size is very less compared to Heap memory.
Difference:
Parameter | Stack Memory | Heap Space |
---|---|---|
Application | Stack is used in parts, one at a time during execution of a thread | The entire application uses Heap space during runtime |
Size | Stack has size limits depending upon OS and is usually smaller then Heap | There is no size limit on Heap |
Storage | Stores only primitive variables and references to objects that are created in Heap Space | All the newly created objects are stored here |
Order | It is accessed using Last-in First-out (LIFO) memory allocation system | This memory is accessed via complex memory management techniques that include Young Generation, Old or Tenured Generation, and Permanent Generation. |
Life | Stack memory only exists as long as the current method is running | Heap space exists as long as the application runs |
Efficiency | Comparatively much faster to allocate when compared to heap | Slower to allocate when compared to stack |
Allocation/Deallocation | This Memory is automatically allocated and deallocated when a method is called and returned respectively | Heap space is allocated when new objects are created and deallocated by Gargabe Collector when they are no longer referenced |
↥ back to top
JVM is a program which takes Java bytecode and converts the byte code (line by line) into machine understandable code. JVM perform some particular types of operations:
Loading of code
Verification of code
Executing the code
It provide run-time environment to the users
Types of Memory areas allocated by the JVM:
1. Classloader: Classloader is a subsystem of JVM that is used to load class files.
2. Class(Method) Area: Class(Method) Area stores per-class structures such as the runtime constant pool, field and method data, the code for methods.
3. Heap: It is the runtime data area in which objects are allocated.
4. Stack: Java Stack stores frames.It holds local variables and partial results, and plays a part in method invocation and return. Each thread has a private JVM stack, created at the same time as thread.
5. Program Counter Register: PC (program counter) register. It contains the address of the Java virtual machine instruction currently being executed.
6. Native Method Stack: It contains all the native methods used in the application.
↥ back to top
The automatic conversion of primitive data types into its equivalent Wrapper type is known as boxing and opposite operation is known as unboxing.
Example: Autoboxing
/** * Autoboxing */class BoxingExample { public static void main(String args[]) { int a = 50; Integer a2 = new Integer(a); // Boxing Integer a3 = 5; // Boxing System.out.println(a2 + " " + a3); } }
Example: Unboxing
/** * Unboxing */class UnboxingExample { public static void main(String args[]) { Integer i = new Integer(50); int a = i; System.out.println(a); } }
↥ back to top
1. Transient:
The transient modifier tells the Java object serialization subsystem to exclude the field when serializing an instance of the class. When the object is then deserialized, the field will be initialized to the default value; i.e. null for a reference type, and zero or false for a primitive type.
Example:
/** * Transient */public transient int limit = 55; // will not persistpublic int b; // will persist
2. Volatile:
The volatile modifier tells the JVM that writes to the field should always be synchronously flushed to memory, and that reads of the field should always read from memory. This means that fields marked as volatile can be safely accessed and updated in a multi-thread application without using native or standard library-based synchronization.
Example:
/** * Volatile */public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) { } } public void stop() { active = false; } }
↥ back to top
An assertion allows testing the correctness of any assumptions that have been made in the program. Assertion is achieved using the assert statement in Java.
While executing assertion, it is believed to be true. If it fails, JVM throws an error named AssertionError
. It is mainly used for testing purposes during development.
The assert statement is used with a Boolean expression and can be written in two different ways.
// First way assert expression;// Second wayassert expression1 : expression2;
Example:
/** * Assertions */public class Example { public static void main(String[] args) { int age = 14; assert age <= 18 : "Cannot Vote"; System.out.println("The voter's age is " + age); } }
↥ back to top
1. Final Variable:
Final variables are nothing but constants. We cannot change the value of a final variable once it is initialized.
Example:
/** * Final Variable */class Demo { final int MAX_VALUE = 99; void myMethod() { MAX_VALUE = 101; } public static void main(String args[]) { Demo obj = new Demo(); obj.myMethod(); } }
Output
Exception in thread "main" java.lang.Error: Unresolved compilation problem: The final field Demo.MAX_VALUE cannot be assignedat beginnersbook.com.Demo.myMethod(Details.java:6)at beginnersbook.com.Demo.main(Details.java:10)
2. Blank final variable:
A final variable that is not initialized at the time of declaration is known as blank final variable. We must initialize the blank final variable in constructor of the class otherwise it will throw a compilation error ( Error: variable MAX_VALUE might not have been initialized
).
Example:
/** * Blank final variable */class Demo { // Blank final variable final int MAX_VALUE; Demo() { // It must be initialized in constructor MAX_VALUE = 100; } void myMethod() { System.out.println(MAX_VALUE); } public static void main(String args[]) { Demo obj = new Demo(); obj.myMethod(); } }
Output
100
3. Final Method:
A final method cannot be overridden. Which means even though a sub class can call the final method of parent class without any issues but it cannot override it.
Example:
/** * Final Method */class XYZ { final void demo() { System.out.println("XYZ Class Method"); } }class ABC extends XYZ { void demo() { System.out.println("ABC Class Method"); } public static void main(String args[]) { ABC obj = new ABC(); obj.demo(); } }
↥ back to top
If a primitive type or a string is defined as a constant and the value is known at compile time, the compiler replaces the constant name everywhere in the code with its value. This is called a compile-time constant.
Compile time constant must be:
Declared final
Primitive or String
Initialized within declaration
Initialized with constant expression
They are replaced with actual values at compile time because compiler know their value up-front and also knows that it cannot be changed during run-time.
private final int x = 10;
↥ back to top
access specifiers/modifiers helps to restrict the scope of a class, constructor, variable, method, or data member.
There are four types of access modifiers available in java:
default
– No keyword required, when a class, constructor,variable, method, or data member declared without any access specifier then it is having default access scope i.e. accessible only within the same package.
private
- when declared as a private , access scope is limited within the enclosing class.
protected
- when declared as protocted, access scope is limited to enclosing classes, subclasses from same package as well as other packages.
public
- when declared as public, accessible everywhere in the program.
... /* data member variables */ String firstName="Pradeep"; /* default scope */ protected isValid=true; /* protected scope */ private String otp="AB0392"; /* private scope */ public int id = 12334; /* public scope */ ... ... /* data member functions */ String getFirstName(){ return this.firstName; } /* default scope */ protected boolean getStatus(){this.isValid;} /* protected scope */ private void generateOtp(){ /* private scope */ this.otp = this.hashCode() << 16; }; public int getId(){ return this.id; } /* public scope */ ... .../* inner classes */ class A{} /* default scope */ protected class B{} /* protected scope */ private class C{} /* private scope */ public class D{} /* public scope */ ...
↥ back to top
In Java, all non-static methods are by default virtual functions. Only methods marked with the keyword final
, which cannot be overridden, along with private methods
, which are not inherited, are non-virtual.
Example: Virtual function with Interface
/** * The function applyBrakes() is virtual because * functions in interfaces are designed to be overridden. **/interface Bicycle { void applyBrakes(); }class ACMEBicycle implements Bicycle { public void applyBrakes() { // Here we implement applyBrakes() System.out.println("Brakes applied"); // function } }
↥ back to top
A native method is a Java method (either an instance method or a class method) whose implementation is also written in another programming language such as C/C++. Moreover, a method marked as native cannot have a body and should end with a semicolon:
Main.java:
public class Main { public native int intMethod(int i); public static void main(String[] args) { System.loadLibrary("Main"); System.out.println(new Main().intMethod(2)); } }
Main.c:
#include <jni.h>#include "Main.h"JNIEXPORT jint JNICALL Java_Main_intMethod( JNIEnv *env, jobject obj, jint i) { return i * i; }
Compile and Run:
javac Main.javajavah -jni Maingcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux Main.cjava -Djava.library.path=. Main
Output
4
↥ back to top
If a method is declared as static, it is a member of a class rather than belonging to the object of the class. It can be called without creating an object of the class. A static method also has the power to access static data members of the class.
There are a few restrictions imposed on a static method
The static method cannot use non-static data member or invoke non-static method directly.
The this
and super
cannot be used in static context.
The static method can access only static type data ( static type instance variable ).
There is no need to create an object of the class to invoke the static method.
A static method cannot be overridden in a subclass
Example:
/** * Static Methods */class Parent { static void display() { System.out.println("Super class"); } }public class Example extends Parent { void display() // trying to override display() { System.out.println("Sub class"); } public static void main(String[] args) { Parent obj = new Example(); obj.display(); } }
This generates a compile time error. The output is as follows −
Example.java:10: error: display() in Example cannot override display() in Parentvoid display() // trying to override display() ^overridden method is static1 error
↥ back to top
What is the structure and features of using a lambda expression? A lambda is a set of instructions that can be separated into a separate variable and then repeatedly called in various places of the program.
The basis of the lambda expression is the lambda operator , which represents the arrow ->
. This operator divides the lambda expression into two parts: the left side contains a list of expression parameters, and the right actually represents the body of the lambda expression, where all actions are performed.
The lambda expression is not executed by itself, but forms the implementation of the method defined in the functional interface. It is important that the functional interface should contain only one single method without implementation.
interface Operationable { int calculate ( int x , int y ); }public static void main ( String [] args) { Operationable operation = (x, y) - > x + y; int result = operation.calculate ( 10 , 20 ); System.out.println (result); // 30 }
In fact, lambda expressions are in some way a shorthand form of internal anonymous classes that were previously used in Java.
Deferred execution lambda expressions - it is defined once in one place of the program, it is called if necessary, any number of times and in any place of the program.
The parameters of the lambda expression must correspond in type to the parameters of the functional interface method:
operation = ( int x, int y) - > x + y;// When writing the lambda expression itself, the parameter type is allowed not to be specified: (x, y) - > x + y;// If the method does not accept any parameters, then empty brackets are written, for example: () - > 30 + 20 ;// If the method accepts only one parameter, then the brackets can be omitted: n - > n * n;
Trailing lambda expressions are not required to return any value.
interface Printable { void print( String s ); } public static void main ( String [] args) { Printable printer = s - > System.out.println(s); printer.print("Hello, world"); }// _ Block lambda - expressions_ are surrounded by curly braces . The modular lambda - expressions can be used inside nested blocks, loops, `design the if ` ` switch statement ', create variables, and so on . d . If you block a lambda - expression must return a value, it explicitly applies `statement return statement ' :Operationable operation = ( int x, int y) - > { if (y == 0 ) { return 0 ; } else { return x / y; } };
Passing a lambda expression as a method parameter
interface Condition { boolean isAppropriate ( int n ); }private static int sum ( int [] numbers, Condition condition) { int result = 0 ; for ( int i : numbers) { if (condition.isAppropriate(i)) { result + = i; } } return result; }public static void main ( String [] args) { System.out.println(sum ( new int [] { 0 , 1 , 0 , 3 , 0 , 5 , 0 , 7 , 0 , 9 }, (n) - > n ! = 0 )); }
↥ back to top
Access to external scope variables from a lambda expression is very similar to access from anonymous objects.
immutable ( effectively final - not necessarily marked as final) local variables;
class fields
static variables.
The default methods of the implemented functional interface are not allowed to be accessed inside the lambda expression.
↥ back to top
If the method existing in the class already does everything that is necessary, then you can use the method reference mechanism (method reference) to directly pass this method. The result will be exactly the same as in the case of defining a lambda expression that calls this method.
Example:
private interface Measurable { public int length(String string); }public static void main ( String [] args) { Measurable a = String::length; System.out.println(a.length("abc")); }
Method references are potentially more efficient than using lambda expressions. In addition, they provide the compiler with better information about the type, and if you can choose between using a reference to an existing method and using a lambda expression, you should always use a method reference.
↥ back to top
on the static method;
per instance method;
to the constructor.
↥ back to top
Nested Inner class can access any private instance variable of outer class. Like any other instance variable, we can have access modifier private, protected, public and default modifier.
Example:
/** * Inner Class */class Outer { class Inner { public void show() { System.out.println("In a nested class method"); } } } class Main { public static void main(String[] args) { Outer.Inner in = new Outer().new Inner(); in.show(); } }
A subclass is class which inherits a method or methods from a superclass.
Example:
/** * Sub Class */class Car { //...} class HybridCar extends Car { //...}
↥ back to top
1. Static Class Loading:
Creating objects and instance using new
keyword is known as static class loading. The retrieval of class definition and instantiation of the object is done at compile time.
Example:
/** * Static Class Loading */class TestClass { public static void main(String args[]) { TestClass tc = new TestClass(); } }
2. Dynamic Class Loading:
Loading classes use Class.forName()
method. Dynamic class loading is done when the name of the class is not known at compile time.
Example:
/** * Dynamic Class Loading */Class.forName (String className);
↥ back to top
1. Runtime Class:
The java.lang.Runtime class is a subclass of Object class, provide access to the Java runtime system. The runtime information like memory availability, invoking the garbage collector, etc.
Example:
/** * Runtime Class */public class RuntimeTest { static class Message extends Thread { public void run() { System.out.println(" Exit"); } } public static void main(String[] args) { try { Runtime.getRuntime().addShutdownHook(new Message()); System.out.println(" Program Started..."); System.out.println(" Wait for 5 seconds..."); Thread.sleep(5000); System.out.println(" Program Ended..."); } catch (Exception e) { e.printStackTrace(); } } }
2. System Class:
The purpose of the System class is to provide access to system resources. It contains accessibility to standard input, standart output, error output streams, current time in millis, terminating the application, etc.
↥ back to top
1. Using new keyword:
MyObject object = new MyObject();
2. Using Class.forName():
MyObject object = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();
3. Using clone():
MyObject anotherObject = new MyObject();MyObject object = (MyObject) anotherObject.clone();
4. Using object deserialization:
ObjectInputStream inStream = new ObjectInputStream(anInputStream );MyObject object = (MyObject) inStream.readObject();
↥ back to top
Immutable objects are objects that don't change. A Java immutable object must have all its fields be internal, private final fields. It must not implement any setters. It needs a constructor that takes a value for every single field.
Creating an Immutable Object:
Do not add any setter method
Declare all fields final and private
If a field is a mutable object create defensive copies of it for getter methods
If a mutable object passed to the constructor must be assigned to a field create a defensive copy of it
Don't allow subclasses to override methods.
/** * Immutable Object */public class DateContainer { private final Date date; public DateContainer() { this.date = new Date(); } public Date getDate() { return new Date(date.getTime()); } }
↥ back to top
Immutable class means that once an object is created, we cannot change its content. In Java, all the wrapper classes (like Integer, Boolean, Byte, Short) and String class is immutable.
Rules to create immutable classes:
The class must be declared as final
Data members in the class must be declared as final
A parameterized constructor
Getter method for all the variables in it
No setters
/** * Immutable Class */public final class Employee { final String pancardNumber; public Employee(String pancardNumber) { this.pancardNumber = pancardNumber; } public String getPancardNumber() { return pancardNumber; } }
↥ back to top
Bootstrap ClassLoader is repsonsible for loading standard JDK classs files from rt.jar and it is parent of all class loaders in java. There are three types of built-in ClassLoader in Java:
1. Bootstrap Class Loader: It loads JDK internal classes, typically loads rt.jar and other core classes for example java.lang.* package classes
2. Extensions Class Loader: It loads classes from the JDK extensions directory, usually $JAVA_HOME/lib/ext directory.
3. System Class Loader: It loads classes from the current classpath that can be set while invoking a program using -cp or -classpath command line options.
/** * ClassLoader */import java.util.logging.Level;import java.util.logging.Logger;public class ClassLoaderTest { public static void main(String args[]) { try { // printing ClassLoader of this class System.out.println("ClassLoader : " + ClassLoaderTest.class.getClassLoader()); // trying to explicitly load this class again using Extension class loader Class.forName("Explicitly load class", true, ClassLoaderTest.class.getClassLoader().getParent()); } catch (ClassNotFoundException ex) { Logger.getLogger(ClassLoaderTest.class.getName()).log(Level.SEVERE, null, ex); } } }
↥ back to top
Different ways to create an object in Java
Using new Keyword:
class ObjectCreationExample{String Owner; }public class MainClass {public static void main(String[] args) {// Here we are creating Object of JBT using new keywordObjectCreationExample obj = new ObjectCreationExample(); } }
Using New Instance (Reflection)
class CreateObjectClass {static int j = 10;CreateObjectClass() {i = j++; }int i;@Overridepublic String toString() {return "Value of i :" + i; } }class MainClass {public static void main(String[] args) {try {Class cls = Class.forName("CreateObjectClass");CreateObjectClass obj = (CreateObjectClass) cls.newInstance();CreateObjectClass obj1 = (CreateObjectClass) cls.newInstance();System.out.println(obj);System.out.println(obj1); } catch (ClassNotFoundException e) {e.printStackTrace(); } catch (InstantiationException e) {e.printStackTrace(); } catch (IllegalAccessException e) {e.printStackTrace(); } } }
Using Clone:
class CreateObjectWithClone implements Cloneable {@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); }int i;static int j = 10;CreateObjectWithClone() {i = j++; }@Overridepublic String toString() {return "Value of i :" + i; } }class MainClass {public static void main(String[] args) {CreateObjectWithClone obj1 = new CreateObjectWithClone();System.out.println(obj1);try {CreateObjectWithClone obj2 = (CreateObjectWithClone) obj1.clone();System.out.println(obj2); } catch (CloneNotSupportedException e) {e.printStackTrace(); } } }
Using ClassLoader
class CreateObjectWithClassLoader {static int j = 10;CreateObjectWithClassLoader() {i = j++; }int i;@Overridepublic String toString() {return "Value of i :" + i; } }public class MainClass {public static void main(String[] args) {CreateObjectWithClassLoader obj = null;try {obj = (CreateObjectWithClassLoader) new MainClass().getClass() .getClassLoader().loadClass("CreateObjectWithClassLoader").newInstance(); // Fully qualified classname should be used. } catch (InstantiationException e) {e.printStackTrace(); } catch (IllegalAccessException e) {e.printStackTrace(); } catch (ClassNotFoundException e) {e.printStackTrace(); }System.out.println(obj); } }
↥ back to top
The Object class is the parent class of all the classes in java by default.
Method | Description |
---|---|
public final Class getClass() | returns the Class class object of this object. The Class class can further be used to get the metadata of this class. |
public int hashCode() | returns the hashcode number for this object. |
public boolean equals(Object obj) | compares the given object to this object. |
protected Object clone() throws CloneNotSupportedException | creates and returns the exact copy (clone) of this object. |
public String toString() | returns the string representation of this object. |
public final void notify() | wakes up single thread, waiting on this object's monitor. |
public final void notifyAll() | wakes up all the threads, waiting on this object's monitor. |
public final void wait(long timeout)throws InterruptedException | causes the current thread to wait for the specified milliseconds, until another thread notifies (invokes notify() or notifyAll() method). |
public final void wait(long timeout,int nanos)throws InterruptedException | causes the current thread to wait for the specified milliseconds and nanoseconds, until another thread notifies (invokes notify() or notifyAll() method). |
public final void wait()throws InterruptedException | causes the current thread to wait, until another thread notifies (invokes notify() or notifyAll() method). |
protected void finalize()throws Throwable | is invoked by the garbage collector before object is being garbage collected. |
↥ back to top
An optional value Optional
is a container for an object that may or may not contain a value null
. Such a wrapper is a convenient means of prevention