Develop By : Prof. Uday Shah (HOD - IT)
Introduction to Java and OOP
1. History and Features of Java
-
Java was developed by James Gosling and his team at Sun Microsystems in 1991 and released in 1995.
-
It was initially called Oak and later renamed Java.
-
Java was designed as a platform-independent language for embedded systems.
-
One of Java's key features is its "Write Once, Run Anywhere" capability.
-
Java is object-oriented, which makes programs modular and reusable.
-
It supports automatic memory management through garbage collection.
-
Java has strong security features, making it suitable for web applications.
-
It supports multi-threading for better performance in concurrent applications.
-
Java is robust because of its strong type checking and exception handling.
-
It is widely used in mobile, web, desktop, and enterprise applications.
-
Java continues to evolve with regular updates from Oracle.
-
The language is known for its simplicity and portability.
2. Java Virtual Machine (JVM)
-
JVM is a part of the Java Runtime Environment (JRE).
-
It interprets Java bytecode and converts it into machine code for execution.
-
JVM is platform-dependent, but Java bytecode is platform-independent.
-
It provides a secure execution environment for Java programs.
-
JVM manages memory allocation and garbage collection automatically.
-
It loads classes dynamically during program execution.
-
JVM uses Just-In-Time (JIT) compilation to improve performance.
-
It provides stack-based architecture for instruction execution.
-
JVM handles exception management in Java applications.
-
It has different implementations for different operating systems.
-
JVM ensures that programs adhere to Java's security model.
-
Without JVM, Java programs cannot be executed.
3. JDK (Java Development Kit)
-
JDK is a complete software development kit required to develop Java applications.
-
It includes the JRE (Java Runtime Environment) and development tools.
-
The JDK contains the Java compiler (
javac
) to compile Java code into bytecode. -
It also includes tools like
javadoc
for documentation andjdb
for debugging. -
JDK provides libraries, APIs, and other utilities required for development.
-
Different versions of JDK exist (Standard Edition, Enterprise Edition, etc.).
-
It supports both command-line and IDE-based Java development.
-
JDK updates regularly to include new features and security patches.
-
Developers must install JDK to write and run Java applications.
-
JDK includes the Java Archive (JAR) tool for packaging applications.
-
JDK can be installed on various operating systems like Windows, Linux, and macOS.
-
JDK is essential for both beginners and advanced Java developers.
4. JRE (Java Runtime Environment)
-
JRE provides the runtime environment for executing Java applications.
-
It includes the JVM and class libraries necessary for execution.
-
Unlike JDK, JRE does not include development tools like compilers.
-
Users who only need to run Java applications can install JRE instead of JDK.
-
JRE handles class loading, memory management, and security.
-
It includes Java core libraries like java.lang, java.util, etc.
-
JRE is platform-specific but supports platform-independent bytecode.
-
It is essential for running applets, applications, and servlets.
-
JRE is lighter compared to JDK because it lacks development utilities.
-
It supports plug-ins to run Java applications inside web browsers.
-
JRE works closely with the JVM to provide an execution environment.
-
Developers must distribute applications compatible with JRE versions.
5) Java Program Structure
-
A basic Java file contains one public class whose name must match the filename (e.g.,
Main.java
→public class Main
). -
The entry point of a standalone app is the
public static void main(String[] args)
method. -
Code is organized into packages; the optional
package
statement must be the first line (before imports). -
The
import
statements allow you to reference classes without fully qualified names. -
A class typically defines fields (state) and methods (behavior); access is controlled with modifiers like
public
,private
,protected
. -
Comments document code: single-line
//
, multi-line/* ... */
, and Javadoc/** ... */
. -
Constants are commonly declared with
static final
and named inUPPER_SNAKE_CASE
. -
Only one public top‑level class is allowed per
.java
file; other top‑level classes in the file must be package‑private. -
Compilation (
javac
) turns.java
into.class
bytecode; execution (java
) runs it on the JVM. -
The static context (e.g.,
static
methods/blocks) belongs to the class, not any particular object. -
Exception handling (
try/catch/finally
orthrows
) shapes how error conditions are managed. -
Typical source layout mirrors packages (e.g.,
com/example/app/Main.java
).
6) Data Types
-
Java has 8 primitive types:
byte
,short
,int
,long
,float
,double
,char
, andboolean
. -
Reference types include classes, arrays, interfaces, and enums; variables hold references, not the objects themselves.
-
Integer types differ by size and range (
byte
8‑bit,short
16‑bit,int
32‑bit,long
64‑bit). -
Floating‑point types
float
(single precision) anddouble
(double precision) follow IEEE‑754. -
char
is a 16‑bit unsigned UTF‑16 code unit; some Unicode characters need surrogate pairs. -
boolean
has onlytrue
andfalse
; it does not convert to numbers. -
Literals:
123
,0b1010
,0xFF
,1_000
,3.14
,'A'
,true
,"text"
,123L
,3.14f
. -
Type casting can be implicit (widening) or explicit (narrowing) with potential precision loss.
-
Primitive variables of fields get default values; local primitives do not—must be initialized.
-
Wrappers (e.g.,
Integer
) provide object counterparts to primitives for collections and utilities. -
Overflow/underflow wraps for integers; floating‑point has special values like
NaN
andInfinity
. -
Strings are reference types, immutable, and not primitives (despite special literal syntax).
7) Variables
-
Declared with a type and name; may be initialized at declaration (e.g.,
int count = 0;
). -
Scopes: block/local scope (inside
{}
), parameter scope (method params), and class scope (fields). -
Lifetimes: local variables exist while their block executes; objects live until unreachable and collected.
-
Field kinds: instance fields (per object) vs.
static
fields (shared by the class). -
Final variables become constants after first assignment; for object references, the reference can’t change but the object might.
-
Default values apply to fields (
0
,false
,null
), not to local variables. -
Shadowing occurs when a local/parameter name hides a field with the same name; use
this
to disambiguate. -
Parameters are passed by value; for object refs, the reference value is copied (not the object).
-
Naming uses lowerCamelCase; be descriptive and avoid abbreviations that reduce clarity.
-
Varargs (
type... args
) allow methods to accept a variable number of arguments. -
You can group related constants with
enum
instead of multipleint
orString
constants. -
Proper initialization order matters: fields → instance initializers → constructor body.
8) Operators
-
Arithmetic:
+ - * / %
for numeric types;/
on integers truncates toward zero. -
Unary:
+ - ++ -- !
and bitwise complement~
; prefix/postfix++/--
differ in evaluation order. -
Relational:
== != < > <= >=
compare primitives; for objects,==
compares references, not content. -
Logical:
&&
and||
are short‑circuiting;&
and|
on booleans evaluate both sides. -
Assignment and compound assignments:
=
,+=
,-=
,*=
, etc., with implicit casts. -
Ternary conditional:
condition ? expr1 : expr2
returns one of two expressions. -
Bitwise/shift:
& | ^ << >> >>>
operate on integer types for low‑level manipulation. -
instanceof checks type compatibility at runtime (works with classes, interfaces, and null‑safe patterning in newer Java).
-
Precedence/associativity determine evaluation order; parentheses improve readability and correctness.
-
Be aware of overflow in integer arithmetic; consider
Math.addExact
to detect it. -
String concatenation uses
+
; heavy concatenation is more efficient withStringBuilder
. -
Side effects inside expressions (e.g.,
i++
in conditions) can reduce clarity—use sparingly.
9) Control Statements
-
Selection:
if
,if-else
, and nested conditionals direct flow based on boolean expressions. -
switch chooses among multiple branches; works with
int
,char
,String
, enums;break
prevents fall‑through. -
Loops:
for
,while
, anddo-while
repeat blocks while conditions hold. -
Enhanced for (
for (T x : collection)
) iterates over arrays/iterables safely and readably. -
break exits the nearest loop/switch; continue skips to the next iteration.
-
Labeled
break
/continue
can control outer loops in nested scenarios. -
try/catch/finally handles exceptional control flow and resource cleanup.
-
try-with-resources automatically closes resources implementing
AutoCloseable
. -
return exits a method optionally returning a value; methods declared
void
return nothing. -
Guard clauses (early returns) simplify complex nested conditionals for readability.
-
Favor clear loop invariants and limit mutable state to avoid subtle bugs.
-
Keep conditions side‑effect free when possible to make flow predictable.
10) Arrays
-
Declare with
type[] name
; allocate withnew type[size]
or initialize with literals{...}
. -
Indices start at
0
and go tolength - 1
; accessing outside throwsArrayIndexOutOfBoundsException
. -
The
length
field (no parentheses) gives the fixed size determined at creation time. -
Arrays are reference types; assigning or passing them copies the reference, not the contents.
-
Default values fill newly allocated arrays (e.g.,
0
,false
,null
for references). -
Multidimensional arrays are arrays of arrays; inner lengths can differ (jagged arrays).
-
Iterate using classic
for
with indices or enhancedfor
for simplicity. -
Use
java.util.Arrays
for utilities likesort
,binarySearch
,copyOf
,equals
, andtoString
. -
Cloning (
arr.clone()
) makes a shallow copy; deep copies require manual copying of contained objects. -
Arrays are efficient but have fixed size; prefer
ArrayList
when dynamic resizing is needed. -
Passing arrays to methods allows in‑place mutation; document whether a method mutates inputs.
-
For performance‑critical code, primitive arrays avoid boxing overhead.
11) Introduction to Classes and Objects
-
A class defines a blueprint: fields (state), methods (behavior), constructors, and nested types.
-
An object is an instance of a class created with
new
; multiple objects share the class definition. -
Encapsulation hides implementation details using access modifiers and exposes a clean API.
-
Methods can be overloaded (same name, different parameter lists) to offer varied usage.
-
Class members can be
static
(belong to the class) or instance members (belong to each object). -
Inheritance (
extends
) enables code reuse and polymorphism; child classes inherit accessible members. -
Interfaces (
implements
) specify capabilities a class promises to provide. -
toString
,equals
, andhashCode
should be overridden meaningfully for domain objects. -
Composition (objects containing other objects) is often preferred over deep inheritance.
-
Objects reside on the heap; references are stored in variables and passed by value.
-
Packages group related classes; visibility rules (public/protected/package/private) control access.
-
Good class design focuses on cohesion, low coupling, and clear responsibilities (e.g., SRP).
12) Constructors
-
Constructors initialize new objects; their name matches the class and they have no return type.
-
If you define no constructor, Java provides a default no‑arg constructor.
-
Parameterized constructors let callers provide initial values for fields.
-
Constructors can be overloaded to support different initialization scenarios.
-
this(...)
invokes another constructor in the same class (must be the first statement). -
super(...)
calls a superclass constructor (also must be first if used). -
Initialization order: field initializers → instance initializer blocks → constructor body.
-
Constructors can perform validation and may throw checked/unchecked exceptions.
-
They are not inherited but are invoked in an inheritance chain (superclass first).
-
Access modifiers on constructors control how objects can be created (e.g., private for singletons/factories).
-
Avoid heavy work or leaking
this
from constructors (e.g., starting threads that escape partially built objects). -
Prefer factory methods when naming or caching instances improves clarity/performance.
13) this
Keyword
-
this
refers to the current object whose method or constructor is executing. -
Use
this.field
to distinguish a field from a parameter with the same name. -
this(...)
calls another constructor in the same class to centralize initialization. -
Methods can return
this
to support fluent APIs or method chaining. -
Pass
this
to another method to provide a reference to the current object. -
In inner classes,
OuterClass.this
names the enclosing instance explicitly. -
this
is not allowed in a static context because no instance exists. -
Avoid exposing
this
during construction (before the object is fully initialized). -
Helps clarify intent when accessing members that could be shadowed by locals.
-
Can be captured by lambdas/anonymous classes, but be mindful of lifecycle leaks.
-
Useful for builder patterns where setters return the same instance.
-
In equals/hashCode implementations,
this
is the left‑hand operand instance.
14) Abstract Class
-
Declared with
abstract
; it cannot be instantiated directly. -
May contain abstract methods (no body) and concrete methods (with implementations).
-
Used to capture shared state and behavior for related subclasses.
-
Subclasses must implement all inherited abstract methods unless they are abstract themselves.
-
Abstract classes can define constructors for initializing common state.
-
They can have fields, including private ones, enabling encapsulation across a hierarchy.
-
Favor an abstract class when you want partial implementation plus shared code.
-
Compared to interfaces, abstract classes allow state and implemented methods without multiple inheritance.
-
Polymorphism: variables typed as the abstract class can hold any subclass instance.
-
You can combine both: a class can extend an abstract class and implement interfaces.
-
Design carefully to avoid deep, brittle inheritance trees; consider composition when suitable.
-
Keep the abstract surface minimal and stable; evolve via protected hooks/template methods.
15) Wrapper Classes
-
Each primitive has a wrapper:
Boolean
,Byte
,Short
,Integer
,Long
,Float
,Double
,Character
. -
Wrappers make primitives usable in collections and APIs that require objects.
-
Autoboxing converts primitives to wrappers automatically; unboxing does the reverse.
-
Wrapper objects are immutable; operations create new objects, not modify existing ones.
-
Utility methods:
parseXxx(String)
,valueOf(String)
, andtoString()
convert between text and numbers. -
Constants like
Integer.MAX_VALUE
andMIN_VALUE
expose type limits. -
compareTo
,compare
, andequals
provide ordering and equality semantics. -
Be mindful of null when unboxing;
NullPointerException
occurs if a null reference is unboxed. -
Number
is a common superclass for numeric wrappers (exceptBoolean
andCharacter
). -
Performance: boxing/unboxing and object allocation add overhead; use primitives in hot loops.
-
Some wrappers (e.g.,
Integer
) cache small values (commonly −128 to 127) for reuse. -
Use wrappers when you need generics, optionality (
null
), or methods; prefer primitives otherwise.