Professional Documents
Culture Documents
class Output
{
public static void main(String args[])
{
Integer i = new Integer(257);
byte x = i.byteValue();
System.out.print(x);
}
}
a.
1
b.
256
c.
0
d.
257
ChatGPT
The correct answer is:
a. 1
Explanation:
a.
Private
b.
Throwable
c.
Static
d.
Protected
ChatGPT
c. Static
Explanation:
In Java, during the serialization process, static members (fields or methods) are
not serialized. The transient keyword is used to indicate that a field should not
be serialized, and it is another way to exclude members from the serialization
process. Private, protected, and public members can all be serialized, but their
behavior may depend on other factors such as the transient modifier. Throwable is a
class in Java, and the question seems to be about class members rather than classes
themselves.
ChatGPT
The correct output will be:
A3 Static
Explanation:
The static block (static{}) is executed when the class is loaded. So, "Static" will
be printed first.
The instance block ({}) is executed when an instance of the class is created.
However, in the main method, an instance of the class is not created (Test1 t =
null;), so the instance block will not be executed in this context.
The constructor public void Test1() is not a valid constructor because the class
name and constructor name should match. The correct constructor should be public
Test1(). Since the constructor is not invoked in the main method, "Constructor"
will not be printed.
Therefore, the correct output is:
A2 Static
java
Copy code
String s1 = new String("hi");
String s2 = "hi";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
In this code:
s1 == s2: This checks if s1 and s2 refer to the same object. Even though both
contain the same sequence of characters, s1 is created using the new keyword,
creating a new object in the heap, while s2 is a string literal, and string
literals are interned in Java. Therefore, s1 == s2 evaluates to false.
s1.equals(s2): This checks if the content of the two strings is the same. Both
strings contain the characters "hi," so s1.equals(s2) evaluates to true.
A1 false true
Explanation:
The code will result in a compiler error because the == operator cannot be used to
compare objects of different types. In this case, i is an Integer object, and f is
a Float object. The comparison i == f is not valid, leading to a compilation error.
Explanation:
A) The File class in Java can indeed be used to represent both files and
directories. It is a versatile class for file-related operations.
C) The mkdirs() method in the File class is used to create a directory and its
parent directories if they do not exist.
1. Lambda Expressions:
----------------------
- Lamda Expression is an Anonymous Function
- not having any modifier
- not having any name
- not having any return
Normal Function
---------------
Lambda Expression
-----------------
- Example 2
-----------
private int getStringLength(String str){
return str.length;
}
1) if the function body has only one statement then no need to include
{}
--------------------------------------------------------------
private int getStringLength(String str){
return str.length();
}
3) No return type
-----------------
private int getStringLength(String str){
return str.length();
}
2. Functional Interface
-----------------------
- Interface which is having only one abstract method and any number of
default and static methods
- Before 1.8, only public abstract methods were only allowed inside the
iterfaces
@FunctionalInterface
public interface MyInterface{ // ok
public void sayHello();
}
@FunctionalInterface
public interface MyInterface{ // error
public void sayHello();
public void sayBye();
}
@FunctionalInterface
public interface MyInterface{ // error
@FunctionalInterface
public interface MyInterface{ // ok
public void sayHello();
@FunctionalInterface
public interface MyInterface{ // ok
public void sayHello();
3. Stream API
=============
- Example :
- I stored data inside the collection
- Now if I want to sort, find min, find max, find avg, etc.
2)
ArrayList<Integer> a1 = new ArrayListL<>();
a1.add(10);
a1.add(20);
a1.add(30);
Stream<Integer> s2 = a1.stream();
- map()
flatmap()
- skip()
limit()
distinct()
Stream<Integer> s2 = a1.stream();
Stream<String> s2 = a1.stream();
Q) Print name of emp having salary > 5000 using stream api
===========================================================
import java.util.ArrayList;
import java.util.List;
- Ex :
------
import java.time.LocalDate;
// 2024-01-01
5. Optional Class:
==================
- The Optional class helps in avoiding null pointer exceptions.
JDK is a development kit containing tools for compiling, debugging, and developing
Java applications.
Key Components:
---------------
Java Compiler (javac):
Translates Java source code into bytecode.
Debugger (jdb):
Helps in debugging Java applications.
JavaDoc:
Generates documentation from Java source code comments.
JRE is a runtime environment containing the JVM and libraries necessary for running
Java applications.
Key Components:
---------------
Java Virtual Machine (JVM):
Executes Java bytecode.
Additional Libraries:
Additional libraries and files necessary for Java applications to run.
##### Structure of java class
=============================
Primitive data structures are char, int, float, double, byte, boolean, long,
short int
- Examples :
------------
1. Keywords
- class, public, static, etc..
2. Identifiers
- variable name
3. Literals
- 123, 123.0, "Hello"
4. Operators
- +, -, /, %
5. Separators
- ,, ;
6. Comments
- //
7. Modifiers
- private, protected
8. Special Symbols
- @
9 Whitespace
-
##### OOPs
==========
OOPs
====
- Smalltalk is the first purely OOPs Language
- Other ways :
- POP : Procedural Oriented Programming Paradigm
- Functional Paradigm
- Logical Paradigm
- Structured Paradigm
// fake
-------
- There are 4 major pillar and 3 minor pillar of OOPs
- Abstraction
- Encapsulation
- Modularity
- Hierarchy
- Polymorphism
- Concurrency
- Persistance
OOPs
====
- In OOPs pillars are divided into 2 parts
- Encapsulation
---------------
- Data Security
- Tightly Coupled Classes
- Inheritance
-------------
- IS-A
- HAS-A
# Class
=======
- Example : Animal, Birds, Cars
- Syntax
---------
- access-modifier class Class-Name{
- fields
- constructors
- methods
- blocks
- nested class
# Object
========
- Example : Elephant, Lion, Eagle, Falcon, Buggati, Rolls Royce
- Object consists of
--------------------
- Identity : name
- State / Attribute : color, breed, age
- Behavior : eat, run (it represents
methods)
2) newInstance() method
3) clone() method
4) deserialization
5) factory method
: Bird flies
- Syntax
--------
access-modifier return-type method-Name(list of parameters){
## Note :
---------
- Default access modifier of class and methods in java is default
#####
1)
class Animal{
public void eat(){
System.out.println("I am eating");
}
output
------
1
2)
class Animal{
public void eat(){
System.out.println("I am eating");
}
output
------
1
I am eating
class Animal{
String color;
int age;
2) By using method
------------------
class Animal{
String color;
int age;
void display(){
System.out.println(color + " " + age);
}
}
}
##### Constructor
=================
- Contructor is a block similar to method having same name as that of
ClassName
- Example :
- And this will initialize every object with same values and is not a
good practice and ends up creating a problem.
2) We can initialize every object with unique values, but that will end
up taking more line of codes as well as more time
- Syntax
--------
class Employee{
String name;
int age;
# 3 types of constructor
========================
1) Default Contructor
---------------------
- It is a no argument constructor
- Compiler calls default constructor only when programmer do not define any
constructor inside a class
- Default Constructor
---------------------
class Test{
String name;
Test(){
super();
}
}
- No argument Constructor
-------------------------
class Test{
String name;
Test(){
}
}
- Parameterized Constructor
---------------------------
class Test{
String name;
Test(String name){
this.name = name;
}
}
- Example
---------
class Animal{
void eat(){
System.out.println("I am eating");
}
}
- Conclusion
------------
- Dog IS-A Animal
- Eagle IS-A Bird
- Advantage
-----------
- Code reusability
- We can achieve polymorphism(method overriding) as well using
inheritance
- Disadvantge
-------------
- Both parent and child class gets tightly coupled
- So if we make any changes inside the parent class then that
will be reflected inside the child class as well
class A{
void showA(){
System.out.println("A class method()");
}
}
class B extends A{
void showB(){
System.out.println("B class method()");
}
2) Multilevel Inheritance
-------------------------
- Suppose we have more than 2 classes, say A, B, and C
- Multilevel Inheritance : class C is extending class B and class B is
extending class A
class A{
void showA(){
System.out.println("A class method()");
}
}
class B extends A{
void showB(){
System.out.println("B class method()");
}
}
class C extends B{
void showC(){
System.out.println("C class method()");
}
3) Hierarchical Inheritance
----------------------------
- Suppose we have more than 2 classes, say A, B, and C
- Hierarchical Inheritance : class C is extending class A and class B is also
extending class A
class A{
void showA(){
System.out.println("A class method()");
}
}
class B extends A{
void showB(){
System.out.println("B class method()");
}
}
class C extends A{
void showC(){
System.out.println("C class method()");
}
- class C extends A, B{
## Note
=======
- We cannot inherit everything from the parent class to child class
- ex:
- We cannot inherit constructor and private member of parent class into
child class
- Association (HAS-A)
---------------------
- Association has 2 forms:
- Aggregaton
- Comnposition
Advantage :
-----------
- Code reusability (same class can be extended
- Cost cutting
- Reduce redundancy (un-necessary code is removed)
- If we are using inheritance between the classes, then classes gets tightly
coupled, means if we make changes onto the property of the parent classes than it
will affect the property of child class
- Bottom to top
class Engine{
}
class Car{
Engine e = new Engine();
}
## 2 forms of Association
==========================
- Aggregation : is a weak bonding
- Example
---------
Weak bonding
------------
class Car{ // container object
}
class Music_Player{ // contained object
Strong Bonding
--------------
class Car{ // container object
}
class Engine{ // contained object
}
- Example 2 :
------------
Weak bonding : College <-> Professor
- 2 types of polymorphism
--------------------------
- Compile Time Polymorphism / Static Polymorphism
- same name
- different class
- same arguments
- number of arguments
- type of arguments
- order of arguments
- Inheritance (IS-A) *** this is mandatory for method overriding
## Method Overloading
=====================
1)
class Test{
void show(){
System.out.println(1);
}
void show(){
System.out.println(2);
}
output
------
- ambiguity error : show() already defined
2)
class Test{
void show(){
System.out.println(1);
}
t.show(100);
}
}
output
------
1
100
output :
--------
abc
class Test{
void show(int a){
System.out.println(a);
}
output :
--------
10
// automatic promotion
----------------------
class Test{
void show(int a){ // this is called
System.out.println("hello");
}
output :
--------
hello
*****
-----
class Test{
void show(Object a){
System.out.println("object");
}
output :
--------
string
*****
-----
class Test{
void show(StringBuffer a){
System.out.println("StringBuffer");
}
output :
--------
ERROR : ambiguous
*****
-----
class Test{
void show(int a, float b){
System.out.println("int float method");
}
output :
--------
int float method
// varargs
*****
-----
class Test{
void show(int a){
System.out.println("int method");
}
void show(int...a){
System.out.println("varargs method");
}
output :
--------
int method
*****
-----
class Test{
void show(int a){
System.out.println("int method");
}
void show(int...a){
System.out.println("varargs method");
}
output :
--------
varargs method
varargs method
class Test{
void show(){
System.out.println(1);
}
}
x se Test class ka show bhi call kar sakte hai, using super() keyword
- Means if we have parent return type in the parent class then we can
have same return type or child return type inside the child class
Example
-------
class Test{
Object show(){
System.out.println("Hello");
return null;
}
}
- this is ok
- because String is the child class of Object Class
1)
class Test{
void show(){
System.out.println("1");
}
}
output
------
ok
2)
class Test{
void show(){
System.out.println("1");
}
}
output
------
error
2) If the parent class is throwing any exception than child class cannot
through any exception or it can through exception of same type or any other
exception of same level
1)
class Test{
void show() throws Exception{ // checked exception
System.out.println("1");
}
}
class Xyz extends Test{
void show() throws Exception{ // checked exception
System.out.println("2");
}
}
output
------
ok
2)
class Test{
void show() throws RuntimeException{ //unchecked exception
System.out.println("1");
}
}
output
------
ok
3)
class Test{
void show() throws RuntimeException{ //unchecked exception
System.out.println("1");
}
}
output
------
ok
##### Relationship between Overriding and Abstract Method
----------------------------------------------------------
Example
-------
-
Interface I{
public abstract void display();
}
output :
--------
ERROR : attempting to access weaker access privileges at void diplay()
-
Solution : make it public
--------------------------
Interface I{
public abstract void display();
}
output :
--------
ok
class Test{
void display(){
System.out.println("1");
}
}
x.display();
}
}
output :
--------
1
2
- Example
---------
1)
class Test{
synchronized void display(){
System.out.println("1");
}
}
output :
--------
2
1
2)
class Test{
strictfp void display(){
System.out.println("1");
}
}
output :
--------
2
1
##### Abstraction
=================
OOPs
====
- In OOPs pillars are divided into 2 parts
- Abstraction
-------------
- Abstraction means Implementation Hiding (How is Vehicle Made?)
- It is used to achieve data security
Scooter
-------
Scooter{
no_of_tyres = 2
start(){
Sop("starts with kick");
}
}
- Since the variable name and method name in both the above object are same,
we can declare one abstract method for code reusability and security
Code :
------
// 100% abstraction
-------------------
abstract class Vehicle{
int no_of_tyres; // we are not telling the no of tyres.. thus
we are hiding the detail
## Abstract Method
-------------------
- abstract method is the method with no implementation, means it doesn't have
a body
- if any class extends the abstract class then it mandatory for that class to
implement the abstract methods of abstract class
- We cannot create object of abstract class but we can create the reference
of abstract class
// 0% abstraction
-----------------
abstract class Vehicle{
int no_of_tyres; // we are not telling the no of tyres.. thus we are
hiding the detail
}
}
### full code
=============
=============
- Syntax :
----------
interface Interface_Name{
After java 8 :
--------------
default methods //
After 9th :
-----------
private methods
- Program
=========
- Method Overridding
--------------------
interface I1{
public abstract void show();
}
class Test implements I1{
void show()
-----------
{
}
}
interface I1{
public abstract void show();
}
// actual code
--------------
interface I1{
protected abstract void show(); // error
}
interface I1{
default abstract void show(); // error
}
interface I1{
void abstract void show();
interface I1{
}
}
interface I1{
void show();
}
}
}
interface I1{
void show(); // public abstract
}
}
}
interface I1{
public abstract void show();
}
interface I2{
public abstract void display();
}
##### Encapsulation
-------------------
- It is used to achieve data security
- Encapsulation means hidding the data
- Plus encapsulation is also a mechanism to wrap class variables and methods
together
- Create getter, setter methods for modifying and viewing those private
class variables
- Example :
-----------
class Employee{
private int empId; // Data Hidding
## Full Code
============
class Employee{
private int empId; // data hidding
System.out.println(e.getEmpId());
}
}
##### this keyword
==================
==================
- this keyword is the reference variable which refers to the object of
current class
- Example
----------
- if we have same name for local variable and for instance variable
- then there occurs a problem (shadowing)
- and to overcome this problem, this keyword comes into picture
class Test{
int i;
void show(){
System.out.println(i);
}
}
t.setValues(10);
class Test{
int i;
void show(){
System.out.println(i);
}
}
t.setValues(10);
t.show(); // 10
}
}
class Test{
int x;
class Test{
void display(){
System.out.println("Hello");
}
void show(){
display(); // this.display(); *****
}
// Hello
class Test{
Test(){
System.out.println("no arg constructor");
}
Test(int a){
this();
System.out.println("parameterised constructor");
}
//
no arg constructor
parameterised constructor
class Test{
Test(){
this(10);
System.out.println("no arg constructor");
}
Test(int a){
System.out.println("parameterised constructor");
}
//
parameterised constructor
no arg constructor
class Test{
void m1(Test t){
System.out.println("Hi");
}
void m2(){
m1(this);
}
//
Hi
class Test{
Test()
{
System.out.println("test class constructor");
}
}
class Test2{
void m1(Test2 t2){
Test t = new Test(this);
}
6) this keyword can be used to return the current class instance from the
method
class Test2{
Test2 m1(Test2 t2){
return this;
}
super = parent
class A{
int a = 10;
}
class B extends A{
int a = 20;
class A{
int i = 10;
}
class B extends A{
int i = 20;
void show(int i){
System.out.println(i); // 30
System.out.println(this.i); // 20
System.out.println(super.i); // 10
}
class A{
void m1(){
System.out.println("m1() method");
}
}
class B extends A{
void show(){
super.m1();
}
//
m1() method
class A{
void m1(){
System.out.println("in class A");
}
}
class B extends A{
void m1(){
System.out.println("in class B");
}
void show(){
m1();
super.m1();
}
//
in class B
in class A
class A{
A(){
System.out.println("in class A");
}
}
class B extends A{
B(){
// super(); //
internally compiler
System.out.println("in class B");
}
//
in class A *****
in class B
## static :
-----------
- static is used for memory management
1)
class Test{
static int a = 10; // ok
void m1(){
static int b = 10; // error
}
psvm(S[] a){
Syso(Test.a); // 10
}
}
everytime I create an object of new employee, name, age and company_name will
get space everytime...
problem is company name is same for all employee and calling it for every
employee object doesn't makes a sense and it will lead to memory problem that's why
what I will do is.. declare company name instance variable as static
such that it will become class level variable and be available for each
instances created for the class
class Employee{
int empid;
String name;
void display(){
Sop(empid + " " + name + " " + company);
}
psvm(S[] a){
Employee e1 = new Employee(100, "Rajiv"); // bas do variable
e1.display(); // 100 Rajiv XYZ
...
}
}
// ek hi time memory allocate hoti hai static variables ko while class loading
class CounterDemo{
int count=0;
CounterDemo(){
count++;
System.out.println(count);
}
//
1
1
1
class CounterDemo{
static int count=0;
CounterDemo(){
count++;
System.out.println(count);
}
// c1, c2, c3 ek ek baar apen liye constructor call karenge aur uske waje se
count 1, 2, 3
class Test{
static void show(){
psvm(S[] a){
Test.show();
}
}
class Test{
void show(){
psvm(S[] a){
Test t = new Test();
t.show();
}
}
## static method directly call kar sakta hu but within a class ****
class Tset{
static void display(){
System.out.println("1");
}
class Tset{
static void display(){
System.out.println("1");
}
// show(); // error
Test.show();
}
}
class Test{
static void show(){
System.out.println("2");
}
}
- staic methods can be accessed directly by class name and doesn't need any
object
- A static method can access only static data. It cannot access non-static
data
- A static method can call only static methods and cannot call a non-static
method
- A static method method cannot refer to this or super keyword in any way
##### static blocks
===================
- if we use static keyword with any block then it becomes a static block
static
{
1)
class Test{
void show(){
psvm(S[] a){
Test t = new Test();
t.show();
}
}
- there is no need to call static block, the moment class loads into the
memory the static block gets executed
class Test{
static{
System.out.println("Hello");
}
}
2)
class Test{
static{
System.out.println("Hello");
}
psvm(S[] a){
System.out.println("Radha");
}
}
//
Hello
Radha
1.6v and above wale me sab block and functions sequentially kaam karte the
after 1.6v sabse pehle static block ko dhund ke execute karega fir agge main
executed hoga
class Test{
static{
System.out.println("Hello");
}
psvm(S[] a){
System.out.println("Radha");
}
static{
System.out.println("Ram");
}
}
//
Hello
Ram
Radha
Uses
====
// static block me mai wo code likhta hu jo mai chahata hu wo class loading ke time
hi execute ho jaye
- example : native methods (wo code jinka code kisi dusri language me
implement kiya jata hai)
// static block is used to initialize the static members
It ensure that at a time one one thread can enter into a critical section
##### Session 4 :
=================
Static Variables:
-----------------
- Static variables, also known as class variables, belong to the class rather
than instances of the class.
- There is only one copy of a static variable, shared among all instances of
the class.
Declaration
-----------
public class MyClass {
static int staticVariable;
}
Characteristics:
----------------
Shared Among Instances:
-----------------------
All instances of the class share the same static variable.
Memory Allocation:
------------------
Memory for a static variable is allocated once when the class is
loaded.
Initialization:
---------------
Static variables are initialized to default values if not explicitly
initialized.
Example:
--------
public class Counter {
static int count = 0;
Counter() {
count++;
}
They can be called using the class name and don't require an instance to be
invoked.
Declaration:
------------
public class MyClass {
static void staticMethod() {
// Method body
}
}
Characteristics:
----------------
No Access to Instance Variables:
--------------------------------
Static methods cannot directly access instance variables; they operate
on class-level data.
Example:
--------
public class MathOperations {
static int add(int a, int b) {
return a + b;
}
Characteristics:
----------------
Objects and Instances:
----------------------
Reference data types are used to create objects and instances of classes.
Null Values:
------------
Reference variables can have a special value called null, indicating that
they are not pointing to any object.
Arrays:
-------
Arrays are reference data types that store multiple elements of
the same type.
Example:
--------
// Creating an array of integers
int[] numbers = new int[]{1, 2, 3, 4, 5};
Interfaces:
-----------
Interfaces can be used as reference data types.
Example:
--------
// Using an interface reference variable
List<String> myList = new ArrayList<>();
```
```
## Reference methoods
---------------------
Definition:
-----------
Reference methods refer to methods associated with objects or classes,
accessed using reference variables.
Characteristics:
----------------
Accessing Object Behavior:
--------------------------
Reference methods allow the invocation of behavior (methods) associated
with objects.
```
```
Size:
-----
Primitive: Have fixed sizes (platform-dependent).
Associated Methods:
-------------------
Primitive: Do not have methods.
Reference: Often come with methods and properties associated with the
objects they represent.
Default Values:
---------------
Primitive: Assigned default values if not explicitly initialized.
Mutability:
-----------
Primitive: Values are immutable.
Static Variable: Scoped to the class itself; shared among all instances
of the class.
Memory Allocation:
------------------
Reference Variable: Memory allocated for each instance of the class.
Static Variable: Memory allocated once for the entire class when it is
loaded.
Access:
-------
Reference Variable: Accessed through instances of the class.
##### Session 5
===============
Constructors:
=============
- In Java, a constructor is a special method that is invoked when an
object is created. It has the same name as the class and is used to initialize the
object's state.
// Constructor
public MyClass(int value) {
this.value = value;
}
// Getter method
public int getValue() {
return value;
}
}
# Pass by reference
===================
////////////
public class Solution{
public static void main(String[] args){
StringBuilder sb = new StringBuilder("Hello");
modifyReference(sb);
# Pass by value
===============
/////////////
public class Solution{
public static void main(String[] args)
{
int x = 10;
modifyValue(x);
System.out.println(x); // 10
}
modifyStringBuilder(myStringBuilder);
//
Before method call: Hello
Inside method: Hello World
After method call: Hello World
## Initializing reference variable of different class
=====================================================
class MyClass {
int value;
// Constructor
public MyClass(int value) {
this.value = value;
}
// Getter method
public int getValue() {
return value;
}
}
//
Retrieved Value: 42
## Heap memory and stack memory
================================
Heap Memory:
===========
Purpose:
--------
Heap memory is used for the dynamic allocation of memory during the
runtime of a Java program.
Characteristics:
----------------
Objects created in the heap exist throughout the program's execution
until they are no longer referenced and become eligible for garbage collection.
Object Lifecycle:
-----------------
Objects in the heap memory are created using the new keyword.
Stack Memory:
=============
Purpose:
--------
Stack memory is used for method execution and managing local variables.
Characteristics:
----------------
Memory in the stack is managed in a last-in, first-out (LIFO) manner,
where the last method called is the first one to finish.
Variable Scope:
---------------
Local variables and method call information exist in the stack.
Memory Allocation:
------------------
Memory for variables in the stack is allocated at the beginning of the
method and released when the method exits.
Summary:
========
Heap Memory:
Used for dynamic memory allocation, storing objects and arrays, managed
by the garbage collector.
Stack Memory:
Used for method execution, managing local variables, and method call
information, memory allocated and deallocated automatically.
##### Session 7
===============
Upcasting:
----------
Definition:
-----------
Upcasting is the process of casting a reference variable of child class to
one of its superclass.
- Example
```
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
// Upcasting
Animal animalRef = myDog;
Downcasting:
------------
Definition:
-----------
Downcasting is the process of casting a reference variable of super class to
one of its childclass.
Key Points:
-----------
Explicit Conversion:
--------------------
Downcasting is an explicit conversion, meaning it requires the casting
operator.
- Example :
-----------
```
class Vehicle {
void start() {
System.out.println("Vehicle starting");
}
}
// Downcasting
Car myCar = (Car) myVehicle;
```
##### Session 8
===============
Final variables, final methods and final class
----------------------------------------------
- Final Variable
----------------
- Once we declare the variable as final, we cannot further re-assign
that variable
- ex:
final int X = 10; // In java, usually the final variables are
written in uppercase letters
X = 20; // error
class final{
public static void main(String[] args){
final int A = 10;
System.out.println(A); // 10 // ok
A = 20;
System.out.println(A); // error : cannot assign value to a final
variable A
}
}
- Final Method
==============
- Once we declare the method as final, we cannot further override that
method inside the sub class
- code
======
class Test{
void mobileNumber(){
System.out.println("7653459871");
}
@Override
void atmPin(){
System.out.println("8944");
}
}
class Final{
public static void main(String[] args){
Thief tf = new Thief;
tf.mobileNumber();
tf.atmPin(); // error : overriden method is final
}
}
- Final Class
==============
- Once we declare the class as final, we cannot further extend that
class on sub class
- final class A{
- code
======
- code
======
final class Test{
void mobileNumber(){
System.out.println("7653459871");
}
@Override
void atmPin(){
System.out.println("8944");
}
}
class Final{
public static void main(String[] args){
Thief tf = new Thief;
tf.mobileNumber();
tf.atmPin(); // error : overriden method is final
}
}
# Functional Interface
======================
- Interface which is having only one abstract method and any number of
default and static methods
- Before 1.8, only public abstract methods were only allowed inside the
iterfaces
@FunctionalInterface
public interface MyInterface{ // ok
public void sayHello();
}
@FunctionalInterface
public interface MyInterface{ // error
public void sayHello();
public void sayBye();
}
@FunctionalInterface
public interface MyInterface{ // error
@FunctionalInterface
public interface MyInterface{ // ok
public void sayHello();
@FunctionalInterface
public interface MyInterface{ // ok
public void sayHello();
- Example
---------
class Outer{
class Inner{
public void show(){
System.out.println("Nested Inner Class");
}
}
}
class Main{
public static void main(String[] args){
Outer.Inner in = new Outer().new Inner();
in.show();
}
}
// output :
-----------
In a nested class method
- Example
---------
class Outer{
void outerMethod(){
System.out.println("outerMethod");
class Inner{
void innerMethod(){
System.out.println("Method Local Inner Class");
}
}
class Main{
public static void main(String[] args){
Outer x = new Outer();
x.outerMethod();
}
}
- output
---------
outerMethod
Method Local Inner Class
- Example
---------
class Test{
void show(){
System.out.println("show() method of super class");
}
}
class Main{
// show() method
void show(){
output :
--------
show() method of super class
- Example
---------
class Outer{
private static void outerMethod(){
System.out.println("outerMethod");
outerMethod();
}
}
}
class Main{
public static void main(String[] args){
Outer.Inner.display();
}
}
- Output
--------
outerMethod
Static Nested Inner Class
##### Enum
==========
- Enums are used to define constant values
- this values will remain constant throughout, their meaning will not
change
# Note:
-------
Enum declaration can be done outside the class or inside the class but
not inside the method
- Hence we can invoke the enum directly from the Command Prompt
## Session 9
============
Key Points:
-----------
Accessible Everywhere:
----------------------
Public members are accessible from any class.
No Restriction on Access:
-------------------------
No restrictions on access within the same package or different packages.
Example:
--------
2. Private:
-----------
Private is the most restrictive access modifier. Members marked as private
are only accessible within the same class.
Key Points:
Limited Access:
---------------
Private members are accessible only within the same class.
Encapsulation:
--------------
Encourages encapsulation by restricting direct access from outside the class.
Example:
--------
public class PrivateExample {
private int privateField;
private void privateMethod() {
// Method body
}
}
3. Protected:
-------------
Protected allows access to members within the same class, same package, and
subclasses (even if they are in different packages).
Key Points:
-----------
Access within Hierarchy:
------------------------
Protected members are accessible within the same class, same package, and
subclasses.
Enhanced Encapsulation:
-----------------------
Provides a balance between encapsulation and extensibility.
Example:
--------
4. Default (Package-Private):
-----------------------------
The default access modifier (also known as package-private) allows access
only within the same package. It is applied when no access modifier is explicitly
specified.
Key Points:
-----------
Package Scope:
--------------
Default members are accessible within the same package.
Example:
--------
class DefaultExample {
int defaultField;
void defaultMethod() {
// Method body
}
}
Summary:
--------
Public: Accessible from any class.
Private: Accessible only within the same class.
Protected: Accessible within the same class, same package, and subclasses.
Default (Package-Private): Accessible within the same package.
Packages:
---------
Package in Java is a way to organize related classes and interfaces into a
single namespace.
-It helps avoid naming conflicts, provides better code organization, and
supports access control.
package com.example.myapp;
Import Statements:
------------------
Import statements in Java are used to bring classes or entire packages into
scope, making them accessible without using their fully qualified names.
import com.example.myapp.MyClass;
Summary:
--------
Packages: Organize related classes and interfaces into a namespace, manage access
control, and support better code organization.
Import Statements: Bring classes or entire packages into scope, reducing verbosity
and enhancing code readability.
Static Imports:
---------------
Static imports in Java allow developers to import the static members of a
class directly into another class.
This feature is particularly useful when working with utility classes or
classes containing a set of related constants or methods.
Constructor Chaining: The process of calling one constructor from another, enabling
the reuse of code and centralizing initialization logic.
// File: Student.java
public class Student {
private String name;
private int age;
// Default constructor
public Student() {
// Default values or additional initialization logic
this("Unknown", 0);
}
// Parameterized constructor
public Student(String name, int age) {
// Shared initialization logic
this.name = name;
this.age = age;
}
// Getter and Setter methods...
}
// File: com.example.school.Student.java
package com.example.school;
// Default constructor
public Student() {
// Default values or additional initialization logic
this("Unknown", 0);
}
// Parameterized constructor
public Student(String name, int age) {
// Shared initialization logic
this.name = name;
this.age = age;
}
The constructor chaining remains the same, and the concept of constructor chaining
is independent of the package structure.
Accessing protected variables and methods outside the package
=============================================================
Key Points:
Access within the Same Class:
-----------------------------
protected members are accessible within the same class.
Access by Subclasses:
---------------------
protected members are accessible by subclasses, even if they are in different
packages.
// File: com.example.packageA.BaseClass.java
package com.example.packageA;
// File: com.example.packageB.DerivedClass.java
package com.example.packageB;
import com.example.packageA.BaseClass;
Garbage Collection: Automatic memory management process in Java that identifies and
cleans up objects that are no longer reachable.
Mark and Sweep: Common garbage collection algorithm involving the identification
and removal of unreachable objects.
Generational Garbage Collection: Division of heap into Young Generation and Old
Generation, with different collection strategies for each.
class MyClass {
public void myMethod() {
// Some code
class MyClass {
public void myMethod() {
// Some code
Summary:
--------
Developers can request garbage collection in Java using System.gc() or
Runtime.getRuntime().gc().
Invoking these methods is a hint to the JVM, but the actual execution depends on
the JVM's decision.
Different ways to make object eligible for garbage collection: (Nulling a reference
variable, Re-assigning a reference variable & island of isolation)
=================================================================
Summary:
--------
Making an object eligible for garbage collection involves ensuring that there are
no live references to it.
3. Island of Isolation:
-----------------------
An "island of isolation" refers to a group of objects that reference each
other but are not accessible from the root of the object graph. If the references
between these objects are broken, the entire group becomes eligible for garbage
collection.
Finalize Method
===============
The finalize() method in Java is a method provided by the Object class that allows
an object to perform cleanup operations before it is garbage collected.
This method is called by the garbage collector just before an object is reclaimed,
giving the object an opportunity to release resources or perform other necessary
cleanup tasks.
```
```
// Other methods...
```
Summary:
--------
The finalize() method is a part of the Object class in Java and is called by the
garbage collector before reclaiming memory.
Null Values:
------------
Wrapper classes can represent null, whereas primitive types cannot.
Java Generics:
--------------
Wrapper classes are often used in Java Generics because generics do not
work with primitive types.
Constant Pools:
---------------
Part of the Java Class file structure containing a table of symbolic
references, including string literals, numeric literals, class/method/field names,
etc.
Numeric Literals:
-----------------
Numeric literals, such as integer and floating-point constants, are
also stored in the constant pool.
Performance Optimization:
-------------------------
The constant pool is used for performance optimizations.
- Example
---------
```
```
Strings in Java are immutable, meaning once a String object is created, its
value cannot be changed.
Key Features:
-------------
Immutable:
----------
Once a String object is created, its content cannot be modified.
String Literals:
----------------
String literals, enclosed in double quotes, are automatically interned in the
String pool. This means that duplicate string literals share the same memory.
String Concatenation:
---------------------
String concatenation in Java can be performed using the + operator. However,
it is recommended to use StringBuilder or StringBuffer for more efficient
concatenation, especially in loops.
Methods:
--------
The String class provides various methods for working with strings, such as
length(), charAt(), substring(), equals(), indexOf(), and more.
They are part of the java.lang package and provide a way to modify the
content of a string.
Common Features:
----------------
Mutable:
--------
Both StringBuffer and StringBuilder are mutable, meaning that their contents
can be changed.
Methods:
--------
StringBuffer provides methods similar to String for concatenation, appending,
reversing, deleting, and inserting.
Comparison Summary:
String:
-------
Immutable.
String pool for memory optimization.
String concatenation efficiency may vary.
StringBuffer:
-------------
Mutable (synchronized).
Thread-safe.
Performance may be impacted in a single-threaded environment.
StringBuilder:
--------------
Mutable (non-synchronized).
Not thread-safe.
Better performance in a single-threaded environment.
String Literals:
----------------
String literals, enclosed in double quotes, are automatically interned in the
String pool. This means that duplicate string literals share the same memory.
## Session 13 & 14
==================
##### Exception
===============
- An unexpected event that occured during the runtime is called as Exception
- Actual Example :
----------------
1) ArithmeticException (Divide by Zero):
----------------------------------------
- We wrote a program to divide 2 numbers what if the 2nd number
which is used for the division operation is zero
try {
int result = numerator / denominator; // This line
will throw ArithmeticException
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
2) NullPointerException:
------------------------
- String str = null;
- int length = str.length(); // This line will throw
NullPointerException
try {
int length = str.length(); // This line will throw
NullPointerException
System.out.println("Length: " + length);
} catch (NullPointerException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
3) ArrayIndexOutOfBoundsException:
----------------------------------
- int[] numbers = {1, 2, 3};
try {
int value = numbers[5]; // This line will throw
ArrayIndexOutOfBoundsException
System.out.println("Value: " + value);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("Error: " + e.getMessage());
}
}
}
4) FileNotFoundException:
-------------------------
- File file = new File("nonexistent.txt");
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
- Actual Example :
----------------
1) What if the numerator is zero, we can say that can't divide a number
by zero
- try
- catch
- throw
- throws
3) And you want some line of code to be executed no matter if the exception arises
or not then
- finally (No matter the exception arises or not this block will get
executed)
- Error
=======
- Error occurs due to lack of system resource
- Error cannot be recovered
- 1 type : Unchecked (Runtime Error)
- Exception
===========
- Exception occurs due to program
- Exception can be recovered
- 2 Types of Exception:
- Checked (Compiletime Exception)
- Unchecked (Runtime Exception)
- NOTE
=======
- You never gets an exception at compile time, that is actually a
warning to you by the compiler that this exception can come at run time.
- Examples
==========
- Mother(Compiler) -> warns son to take the id, purse, etc such that
he should not face an unexpected event during the normal flow
===================
- Checked Exception
===================
- The exception which can be checked by the compiler
====================
- Real World Example
====================
- Mother as a compiler son ko bata sakti hai ki
- PurseNotTakenException
- CompanyIdNotTakenException
- Examples
==========
- ClassNotFoundException
- IOException
- EOFException
- FileNotFoundException
- InterruptedIOException
- NoSuchMethodException
- SQLException
- RemoteException
- InterruptedException
======================
- Unchecked Exception
======================
- The exception which are ignored by the compiler
- Runtime exception
- Example
=========
- ArithmeticException
- ClassCastException
- NullPointerException
- IndexOutOfBoundException
- ArrayIndexOutOfBoundException
- StringIndexOutOfBoundException
- IllegalArgumentException
- NumberFormatException
- throws :
----------
- throws keyword is used to declare the exception while creating
function itself
Finalize Method
===============
The finalize() method in Java is a method provided by the Object class that allows
an object to perform cleanup operations before it is garbage collected.
This method is called by the garbage collector just before an object is reclaimed,
giving the object an opportunity to release resources or perform other necessary
cleanup tasks.
```
```
##### finally block
====================
- if inside try block you provide jump or break statement than too finally
block will get executed. But before the jump statements.
- try -> finally -> break, continue, etc...
- An exception is first thrown from the top of the stack and if it is not
caught, it drops down the call stack to the previous method.
// every method will have 2 different paths, either handle the exception using try-
catch block or it can forward the exception to it's previous calling block
class Test{
public static void main(String[] args){
m1(); #1
}
output
======
exception at line number #1, #2, #3
Solution
========
class Test{
public static void main(String[] args){
m1(); #1
}
}
public static void m2(){
System.out.println(10/0); #3
}
}
Output
======
Exception Handled by M1
try{
int a = 10/ 0;
System.out.println(a); #1
int b[5];
System.out.println(b[7); #2
String c = null;
c.toUpperCase(); #3
}
catch(ArrayIndexOutOfBoundException e){
}
catch(ArithmeticException e){
}
catch(Exception e){
- Exception is the super class of all the exceptions and it can handle any
type of exception
- Exception (super class) must be placed at the last position inside the
multi catch block
Code
====
class Test{
public static void main(String[] args){
try{
int a = 10, b = 2, c;
c = a / b;
System.out.println(c); // ArithmeticException fi b = 0
- If these exceptions are not handled properly, then the program would fail
to compile.
Session 15:
===========
java.io & java.nio Package
===========================
Serialization
-------------
- Serialization is the process of converting the state of an object into
byte-stream such that we can transfer the state of an object over a network or we
can save it inside a file
public Solution(){
}
2)
Serial.java
===========
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
try
{
// write data to file
fos = new FileOutputStream("test.txt");
// How to serialize
oos.writeObject(student);
System.out.println("State of an object is saved into a
file...");
}
catch(IOException e)
{
e.printStackTrace();
}
finally{
try{
if(oos != null){
oos.close();
}
if(fos != null){
fos.close();
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
}
De-serialization
----------------
- De-serialization is the process of converting byte-stream into the state of
an object such that we can reconstruct the byte-stream into human understandable
data
try
{
fis = new FileInputStream("test.txt");
ois = new ObjectInputStream(fis);
// Deserialize
Solution student = (Solution) ois.readObject();
System.out.println("After De-serializing : ");
System.out.println(student.getName());
System.out.println(student.getEmail());
System.out.println(student.getAge());
System.out.println(student.getAdd());
}
catch(IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
finally
{
try
{
if(ois != null){
ois.close();
}
if(fis != null){
fis.close();
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
}
##### Transient
===============
- Transient is a keyword in java, which tell the compiler that we do not want
to serialize this data member from the class
- Example
---------
import java.io.Serializable;
public class Solution implements Serializable
{
private String name;
private String email;
transient private int age;
--------------------------
private String address;
...
- Shallow Copy
==============
- Shallow Copy copies the reference of the object and not the actual object,
so if some other object updates the value of that object which is shallow copied
using the reference
// full code
------------
class Address{
private String city;
private String street;
@Override
public String toString(){
return "Address : City = " + city + " and Street = " +
street;
}
}
class Person{
private String name;
private Address address;
@Override
public String toString(){
return "Person : Name = " + name + " and Address : " +
address;
}
}
public class Solution{
public static void main(String[] args){
Address originalAddress = new Address("Banglore", "Road
1");
// Shallow Copy
Person shallowCopy = originalPerson;
}
}
/*
Output
======
Original Person : Person : Name = Rajiv and Address : Address : City = Mumbai and
Street = Road 1
Shallow Copy Person : Person : Name = Rajiv and Address : Address : City = Mumbai
and Street = Road 1
*/
- Deep Copy
===========
- Deep copies the actual object itself, so now if any object changes the
value of the object from which deep copy created the copy of object for itself...
the changes will not affect the deep copy data at all
full code
=========
class Address{
private String city;
public Address(String city){
this.city = city;
}
@Override
public String toString(){
return "City = " + city;
}
}
class Person{
private String name;
private Address address;
@Override
public String toString(){
return "Name : Person = " + name + " and Address : " +address;
}
}
// Shallow Copy
// Person shallowCopy = oriPerson;
// Deep Copy
Person deepCopy = new Person(oriPerson.getName(), new
Address(oriPerson.getAddress().getCity()));
oriAddress.setCity("Pune");
}
}
/*
Output
------
Shallow Copy Person : Name : Person = Rajiv and Address : City = Banglore
*/
// code
-------
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
InputStream:
============
- The InputStream interface is designed for reading bytes from a source
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
Writer:
=======
- The Writer interface is designed for writing characters to a destination.
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
try{
// writing to a file
writer = new FileWriter("test.txt");
String content = "Hello, Writer!";
writer.write(content);
Session 16:
===========
Object Class & java.util Package
================================
Despite its widespread usage in older Java code, it has several limitations
and is considered outdated.
Key Points:
-----------
Mutable:
--------
The Date class is mutable, allowing changes to its values after creation.
Deprecated Methods:
-------------------
Many methods within the Date class are deprecated due to issues and
limitations.
Time in Milliseconds:
---------------------
Time is represented in milliseconds since the epoch (January 1, 1970,
00:00:00 GMT).
```
import java.util.Date;
```
Calendar Class:
---------------
The Calendar class, also in the java.util package, is an abstract class
providing methods for date and time manipulation.
Key Points:
-----------
Locale-Sensitive:
-----------------
Calendar is locale-sensitive, considering regional differences in the first day of
the week and months.
Field Access:
-------------
Access and modification of individual fields such as year, month, day, hour,
minute, and second.
Month Indexing:
---------------
Months are zero-indexed, i.e., January is 0 and December is 11.
Extensibility:
--------------
The Calendar class is extensible, allowing concrete implementations like
GregorianCalendar.
```
import java.util.Calendar;
```
Key Points:
-----------
Immutable:
----------
Instances of LocalDateTime are immutable, preventing changes after creation.
Modern API:
-----------
The java.time package provides a comprehensive and modern API for dates, times, and
durations
```
import java.time.LocalDateTime;
```
Interview Notes:
----------------
Why is the Date class considered outdated in Java?
--------------------------------------------------
The Date class is considered outdated due to mutability, deprecated methods, and
the lack of modern features like immutability and time zone support.
How does the Calendar class differ from the Date class?
-------------------------------------------------------
The Calendar class provides more functionality for date and time manipulation
compared to the Date class. It is locale-sensitive, allows access to individual
fields, and is extensible.
What are some drawbacks of the Date class in Java?
--------------------------------------------------
Drawbacks include mutability, deprecated methods, poor time zone handling, and the
absence of a modern API.
What advantages does the LocalDateTime class offer over the Date and Calendar
classes?
-----------------------------------------------------------------
LocalDateTime provides immutability, better manipulation features, and is part of
the modern java.time package, addressing many issues with the older date and time
classes.
```
import java.text.SimpleDateFormat;
import java.util.Date;
```
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
try {
// Parsing String to Date
Date parsedDate = sdf.parse(dateString);
System.out.println("Parsed Date: " + parsedDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
```
Object Class: Overriding to String, equals &hashcodemethod
===========================================================
1. toString() Method:
---------------------
```
@Override
public String toString() {
return "MyClass{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
```
```
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
3. hashCode() Method:
---------------------
```
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}
```
Summary:
--------
toString(): Provides a string representation of the object.
equals(Object obj): Checks if two objects are equal based on their content.
Session 22:
===========
### Multithreading
==================
- Q) What is process (task)?
- Program in execution is called as process.
- It is a heavyweight process
- Q) What is thread?
- A thread is a lightweight sub-process.
- Main Thread
-------------
- It is also called as Non-Dameon Thread / User Thread.
- And it is responsible for invoking the main method
- And I have read somewhere the priority of main thread is 5
(Thread.NORM_PRIORITY).
# Application
==============
- Single Threaded : Javascript Programming Language
- Single Processing : DOS OS
- But, if we implement the Runnable interface, our class can still extend
other base class as well as it can implement more interfaces.
- Using runnable will give you an object that can be shared amongst multiple
threads.
1) By implementing Runnable
----------------------------
class MultithreadingDemo implements Runnable{
public void run(){
try{
System.out.println(
"Thread " + Thread.currentThread().getId() + " is running"
);
}
catch(Exception e){
System.out.println("Exception is caught");
}
}
}
2) By extending Thread
-----------------------
class MultithreadDemo extends Thread{
public void run(){
try{
System.out.println(
"Thread "+ Thread.currentThread().getId() + " is running"
);
}
catch(Exception e){
System.out.println("Exception is caught.");
}
}
}
The sleep method is used to pause the execution of the current thread for a
specified period of time.
Parameters:
-----------
millis: The duration in milliseconds for which the thread should sleep.
Example:
```
try {
Thread.sleep(2000); // Sleep for 2 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
```
2. join() Method:
-----------------
The join method is used to wait for a thread to finish its execution before
proceeding with the current thread.
Example:
--------
It is often used to coordinate the activities of multiple threads.
Example :
---------
```
thread.start();
try {
thread.join(); // Wait for the 'thread' to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
```
3. yield() Method:
------------------
The yield method is used to suggest to the scheduler that the current thread is
willing to yield its current time slice.
Behavior:
---------
It does not guarantee that the scheduler will switch to another thread; it is a
hint.
Example:
--------
```
thread1.start();
thread2.start();
}
}
```
Parameters:
-----------
newPriority: The new priority value (an integer between Thread.MIN_PRIORITY and
Thread.MAX_PRIORITY).
Example:
--------
```
thread1.start();
thread2.start();
thread1.setPriority(Thread.MIN_PRIORITY);
thread2.setPriority(Thread.MAX_PRIORITY);
```
5. getPriority() Method:
------------------------
Returns:
--------
An integer representing the priority of the thread.
Example:
--------
```
thread1.start();
```
ThreadGroup Class in Java:
===========================
The ThreadGroup class in Java is a class that provides a way to group
multiple threads into a single unit.
It is part of the java.lang package and is useful for managing and organizing
threads in a hierarchical manner.
Key Concepts:
-------------
Grouping Threads:
-----------------
The primary purpose of ThreadGroup is to group multiple threads together. This
grouping is particularly helpful for managing and controlling the behavior of
related threads.
Hierarchy:
----------
ThreadGroup instances can be organized into a hierarchical structure. Each
ThreadGroup can have subgroups, creating a tree-like structure.
Naming:
-------
Each ThreadGroup is associated with a name, making it easier to identify and manage
groups of threads.
ThreadGroup as a Parent:
------------------------
A ThreadGroup can have child ThreadGroups, forming a parent-child relationship. The
top-level ThreadGroup is the main thread group.
Thread Management:
------------------
The ThreadGroup class provides methods for enumerating the threads within the
group, stopping all threads in the group, and setting the maximum priority of the
threads in the group.
Creating ThreadGroups:
----------------------
public class ThreadGroupExample {
public static void main(String[] args) {
ThreadGroup parentGroup = new ThreadGroup("ParentGroup");
ThreadGroup childGroup = new ThreadGroup(parentGroup, "ChildGroup");
thread1.start();
thread2.start();
}
}
// Starting threads
thread1.start();
thread2.start();
Interview Notes:
----------------
##### Synchronization
=====================
%%%%%%%%%%
Example
=======
- Bank - Joint Account and all the members are trying to withdraw the amount
at same time
- Multithreading says yes this task must be executed, and each one should get
the output
- This leads to the Data Corruption
- Multithreading
================
public void run()
{
// same resource
}
t1.start();
t2.start();
t3.start();
- All the three threads t1, t2, t3 will access the same resource at the same
time in this case
- Synchronization
=================
public synchronized void run()
{
// same resource
}
t1.start();
t2.start();
t3.start();
- At a time single thread will access the same resource in this case
t1.start();
t2.start();
t3.start();
- So the time consuming part where all the 3 threads are supposed to entered
inside the method is already done at a one go.
%%%%%%%%%%
## Race Condition
=================
- There are 2 threads
- One thread is reading from the file
- and One thread is writing to the file
- when one thread is reading from the file and other thread is
writing from the file and vice versa.
## Synchronization
------------------
- Synchronization is technique which ensures that when multiple threads
are sharing the same resource there shouldn't be "Race Condition".
- This lock comes into picture only when an object gets the non-static
synchronized method or block.
- Whichever thread is suppose to execute the synchronized method first,
acquires the lock.
- Other threads have to be in "seeking lock state"
block :- only those statements are protected which are given inside
synchronized block.
# What do you mean by “Thread-Safe” class?
- Thread-safe class means a class having non-static synchronized
methods or methods having non-static synchronized blocks.
class Test {
synchronized void test_function(int n)
{
// synchronized method
for (int i = 1; i <= 3; i++) {
System.out.println(n + i);
try {
Thread.sleep(500);
}
catch (Exception e) {
System.out.println(e);
}
}
}
}
// Driver Class
public class GFG {
// Main function
public static void main(String args[])
{
// only one object
final Test obj = new Test();
a.start();
b.start();
}
}
Output
16
17
18
31
32
33
DeadLock
========
- Even though synchronized method or block is used to avoid "Race Condition",
there can be danger of "DeadLock" inside it.
- Neither this thread can complete it's job and release the lock, nor can
other thread acquire the lock
================
// fake points //
================
=================
// fake points //
=================
##### What are the methods used for Thread communication? Explain them in brief.
- wait()
---------
- It will make thread to release the lock and go to wait pool
- notify()
----------
- It will make thread to move from the wait pool to "seeking lock
state"
- notifyAll()
-------------
- it will make all threads to move from wait pool to seeking lock
state.
Test(T obj){
this.obj = obj;
}
public T getObject(){
return this.obj;
}
}
public class Solution{
public static void main(String[] args){
Test<Integer> tObj = new Test<Integer>(15);
// HERE Integer ACTS AS A TYPE ARGUMENT
System.out.println(tObj.getObject()); // 15
- Type Safety:
--------------
example :
code 1)
a1.add("String1");
a1.add("String2");
a1.add(10); // Compiler allows this
String s1 = (String)a1.get(1);
o/p :
-----
Exception in thread "main" java.lang.ClassCastException:
java.lang.Integer cannot be cast to java.lang.String at
Test.main(Test.java:19)
code 2)
String s1 = a1.get(1);
String s1 = a1.get(2);
}
}
o/p :
-----
15: error: no suitable method found for add(int) al.add(10);
- Conclusion :
--------------
- We do not require type casting every times
System.out.println(
element.getClass().getName() + " = " +element);
}
genericDemo("Hello");
genericDemo(1.0);
}
}
o/p:
----
java.lang.Integer = 100
java.lang.String = Hello
java.lang.Double = 1.0
- So we can say generic method is similar to the normal methods, the only
difference is we can pass type parameter to the method
- And passing a type parameter opens the door for many advantages
- Type-Safety:
Instance of String type argument can deal with String type
data only.
- Generic Classes
------------------
Test(T obj){
this.obj = obj;
}
public T getObject(){
return this.obj;
}
}
System.out.println(tObj.getObject()); // 15
o/p
---
15
Rajiv
- So we can say generic class is similar to the normal classes, the only
difference is we can pass type parameter to the class
- And passing a type parameter opens the door for many advantages
- Type-Safety:
Instance of String type argument can deal with String type
data only.
o/p
----
Hello
100
- example :
import java.util.Arrays;
import java.util.List;
printlist(list1);
printlist(list2);
}
}
- example :
printlist(list1);
printlist(list2);
}
}
- example :
printlist(list1);
printlist(list2);
}
}
- Using reflection we can get information about class, constructor and method
of the unknown object at the runtime.
- Using Reflection we can also invoke the method if we know the method name
and the type parameter. And to do so we use below 2 methods :
- getDeclaredMethod() : It creates object of the method to be invoked
- Class.getDeclaredMethod(name, parametertype)
- invoke() : It invokes a method of the class at runtime.
- Method.invoke(Object, parameter)
- Applications
==============
- The reflection API is mainly used in :
- IDE
- Debugger tools
- Testing tools
- Advantages
============
- Exposure to internals : we can access private members of the class
- Useful for debugging and testing tools.
- framework and libraries : many IDE use this feature for auto
correction and filling the code
- Disadvantages
===============
- Performance Overhead : Reflection operations are slower
- Security Risk : Because we are able to access members of the class
- Complexity in coding part
Lab 25:
Invoke private methods of some other class using reflection.
Create multiple threads using anonymous inner classes.
Create multiple threads using lambda expressions.
%% VS CODE %%
class ExampleClass {
private void privateMethod(String message) {
System.out.println("Private method invoked with message: "
+ message);
}
}