unit 11
unit 11
1. Process-Oriented Model:
o This traditional approach focuses on sequences of tasks or operations. Programs are
conceptualized around "what is happening," with code acting on data.
o This model is effective for smaller, simpler programs. However, as programs grow in
complexity, managing them using this approach becomes difficult.
2. Object-Oriented Model:
o OOP, in contrast, organizes programs around data, represented as objects. It emphasizes
"who is being affected" rather than "what is happening."
o Objects encapsulate data and provide well-defined interfaces to interact with that data.
This shift in focus offers several organizational and maintenance advantages, especially
in complex systems.
1. Abstraction:
o Abstraction is the process of hiding the complex implementation details of a system and
exposing only the necessary features. It helps in managing complexity by simplifying
how we interact with complex systems.
o Example: A car is an abstraction. We interact with it as a single object, without needing
to understand the thousands of components and systems that make it work.
o In OOP, abstraction is achieved through the use of classes and objects, which model real-
world entities with attributes (data) and behaviors (methods).
2. Encapsulation:
o Encapsulation is the technique of bundling data (attributes) and methods (functions) that
manipulate the data into a single unit, or class, and restricting access to some of the
object's components.
o Example: In a car, the gear-shift lever is the interface to the transmission system, hiding
the complex workings of the engine from the user. The driver can operate the car without
needing to know the intricacies of the transmission.
o In Java, encapsulation is implemented through access modifiers such as private,
protected, and public, which control access to the class's data and methods. By
restricting access, encapsulation protects the integrity of the data and prevents misuse.
Encapsulation: public methods can be used to protect private data.
3. Inheritance:
o Inheritance is a mechanism where a new class, known as a subclass, derives properties
and behavior (methods) from an existing class, known as a superclass.
o Example: A Golden Retriever inherits characteristics from the Dog class, which in turn
inherits from the Mammal class, forming a hierarchical classification.
o In Java, inheritance promotes code reusability, as common functionality defined in a
superclass can be inherited by multiple subclasses. It also supports polymorphism,
allowing objects of different subclasses to be treated as objects of a common superclass.
4. Polymorphism:
o Polymorphism allows objects of different classes to be treated as objects of a common
superclass. It also allows a single method or interface to operate on objects of various
types.
o Example: A dog’s sense of smell responds differently based on what it detects, such as
food or a cat. In programming, this allows for methods to be overridden in different
subclasses, providing specific behavior while sharing a common interface.
o In Java, polymorphism is achieved through method overloading (compile-time
polymorphism) and method overriding (runtime polymorphism). This enables flexible
and maintainable code, where the same operation can behave differently on different
classes.
Java 1.0: The initial release of Java was groundbreaking, introducing the concept of platform-
independent, "write once, run anywhere" programming.
Java 1.1: Soon after Java 1.0, Java 1.1 was released. This version introduced substantial
changes, including new library elements, a redefined event handling model, and reconfiguration
of existing features. Java 1.1 also deprecated some of the features from Java 1.0, signaling Java's
continuous evolution.
Java 2 (Version 1.2): The next major release, Java 2, marked the beginning of Java's "modern
age." Java 2 introduced significant enhancements, including the Swing GUI toolkit, the
Collections Framework, and improved the Java Virtual Machine (JVM). Java 2 was repackaged
as J2SE (Java 2 Platform, Standard Edition).
Java 1.3: This version focused on improving and refining the existing features introduced in
Java 2, maintaining source-code compatibility with version 1.2.
Java 1.4: Introduced important features like the assert keyword, chained exceptions, and a
channel-based I/O subsystem. This version also saw enhancements to the Collections
Framework and networking classes.
Java 5 (Version 1.5): A revolutionary release that fundamentally expanded the Java language.
Major new features included generics, annotations, autoboxing and auto-unboxing,
enumerations, the enhanced for-each loop, variable-length arguments (varargs), static import,
formatted I/O, and concurrency utilities. The significance of these features led to the version
being labeled as Java 5 instead of Java 1.5.
Java SE 6:
Java SE 6 (Version 1.6): This version continued to build on the advancements of Java 5, adding
incremental improvements to the API libraries, new packages, and runtime enhancements.
Although no major language features were added, Java SE 6 solidified the changes from Java 5.
Java SE 7:
Java SE 7 (Version 1.7): The first major release after Oracle acquired Sun Microsystems, Java
SE 7 introduced several new features as part of Project Coin, including:
o String in switch statements
o Binary integer literals and underscores in numeric literals
o The try-with-resources statement for automatic resource management
o Type inference with the diamond operator
o Enhanced exception handling with multi-catch and improved type checking
o Fork/Join Framework for parallel programming
o Enhancements to the NIO framework (NIO.2)
Java SE 7 was significant for its improvements to the language and API, especially in simplifying
coding practices and supporting modern multicore processors.
Java, as a programming language, was designed with a specific set of principles in mind that guided its
development. These principles are often referred to as the "Java Buzzwords," and they encapsulate the
core values and features that the language embodies. Below is an exploration of these buzzwords:
1. Simple:
Java was created to be easy to learn, especially for developers familiar with C and C++. By
adopting much of the syntax from C/C++, Java makes the transition to this new language
smooth and intuitive. Java also eliminated the complexities of languages like C++, such as
multiple inheritance and operator overloading, making it simpler and less error-prone.
2. Secure:
Security was a key consideration in the design of Java. It was initially designed for use in
networked environments, which required strong security measures. Java programs run inside a
secure "sandbox" environment provided by the Java Virtual Machine (JVM), which prevents
untrusted code from accessing unauthorized resources.
3. Portable:
Java's portability comes from its "write once, run anywhere" philosophy. Java code is compiled
into an intermediate form called bytecode, which can be executed on any machine that has a
JVM. This makes Java programs highly portable across different platforms, including different
operating systems and hardware architectures.
4. Object-Oriented:
Java is fundamentally an object-oriented programming (OOP) language. This means that the
language is designed around the concept of objects, which combine data and methods. Java's
OOP principles include inheritance, encapsulation, polymorphism, and abstraction, which help
in creating modular, reusable, and scalable software.
5. Robust:
Java was designed with a focus on reliability and error-free code. It emphasizes early error
checking, such as type checking at compile-time and runtime, and it includes features like
garbage collection to manage memory automatically. These features reduce the likelihood of
bugs related to memory management, which are common in languages like C/C++.
6. Multithreaded:
Java provides built-in support for multithreading, which allows the simultaneous execution of
multiple parts of a program. This is essential for developing interactive applications, such as
games or GUIs, and for efficiently utilizing modern multicore processors. Java’s thread
management is designed to be easy to implement, helping developers write responsive, high-
performance programs.
7. Architecture-Neutral:
Java’s architecture-neutral nature means that its programs are not tied to any specific processor
or operating system. This is achieved through the use of bytecode, which can be interpreted by
any JVM, regardless of the underlying architecture. This ensures that Java programs are future-
proof, as they are insulated from changes in hardware and system software.
Java is an interpreted language, where the compiled bytecode is executed by the JVM. Despite
being interpreted, Java achieves high performance through Just-In-Time (JIT) compilation,
which translates bytecode into native machine code at runtime, allowing Java applications to run
almost as fast as native compiled languages.
9. Distributed:
10. Dynamic:
Java is a dynamic language in that it supports dynamic memory allocation and can dynamically
link new classes, methods, or objects during runtime. Java programs carry significant runtime
type information that is used to verify and resolve accesses to objects at runtime, ensuring safe
and efficient code execution
It is because Java programs are compiled into bytecode, which can be executed on any device
or operating system with a compatible Java Virtual Machine (JVM). This means you can write
your code once and run it anywhere, adhering to the principle "Write Once, Run Anywhere"
(WORA). The JVM interprets the bytecode into native machine code specific to the platform,
ensuring consistency and portability across different systems.
2. Key Components:
• Edit
– Create/edit the source code
• Compile
– Compile the source code
• Load
– Load the compiled code
• Verify
– Check against security restrictions
• Execute
– Execute the compiled code
Execution Engine:
o Interpreter: Reads and executes bytecode instructions one at a time. It is
straightforward but can be slower.
o Just-In-Time (JIT) Compiler: Converts bytecode into native machine code just before
execution. This improves performance by reducing interpretation overhead.
o Garbage Collector (GC): Automatically manages memory by reclaiming unused
objects and preventing memory leaks. Various GC algorithms are employed, including
generational, mark-and-sweep, and more.
Native Interface:
o Java Native Interface (JNI): Allows Java code to interact with native applications and
libraries written in other languages like C or C++.
o Java Native Access (JNA): Provides a simpler way to interact with native libraries
without writing JNI code.
Native Method Libraries:
o These are libraries that provide the native implementations required for JVM operations,
such as file system operations or network communications.
3. Execution Flow:
4. JVM Specifications:
Java Virtual Machine Specification: Defines the JVM's architecture and how it should behave.
Java Class File Format Specification: Describes the format of Java class files, including
bytecode and metadata.
5. JVM Implementations: Different JVM implementations may have variations in how they handle
these components, but they all adhere to the JVM specification to ensure compatibility.
Java's primitive data types are the simplest forms of data representation. They are not objects and are
used to represent single values. They are categorized into four groups:
1. Integers:
o byte: 8-bit signed integer. Range: -128 to 127.
o short: 16-bit signed integer. Range: -32,768 to 32,767.
o int: 32-bit signed integer. Range: -2,147,483,648 to 2,147,483,647.
o long: 64-bit signed integer. Range: -9,223,372,036,854,775,808 to
9,223,372,036,854,775,807.
2. Floating-Point Numbers:
o float: 32-bit single-precision floating-point number. Range: 1.4e–045 to 3.4e+038.
o double: 64-bit double-precision floating-point number. Range: 4.9e–324 to 1.8e+308.
3. Characters:
o char: 16-bit Unicode character. Range: 0 to 65,535.
4. Boolean:
o boolean: Represents true or false values.
Variables
A variable in Java is a container for storing data values. Each variable must be declared with a type
before it can be used
Declaration Syntax:
Dynamic Initialization
Scope: Determines where the variable can be accessed. Variables have scope based on where
they are declared.
Lifetime: The duration a variable exists in memory.
Method Scope: Variables declared within a method are only accessible within that method.
Block Scope: Variables declared within a block (e.g., inside {}) are only accessible within that
block.
class DataTypesDemo {
// Integer types
byte b = 10;
short s = 1000;
int i = 200000;
long l = 3000000000L;
// Floating-point types
float f = 3.14f;
double d = 3.14159;
// Character type
char c = 'A';
// Boolean type
// Dynamic Initialization
// Variable Scope
{
int innerVar = 20; // Accessible only within this block
System.out.println("Area of circle with radius " + radius + " is: " + area);
OUTPUT:
Outer Variable: 10
Inner Variable: 20
byte: 10
short: 1000
int: 200000
long: 3000000000
float: 3.14
double: 3.14159
char: A
boolean: true
1.6 Arrays
An array is a collection of variables of the same type that are stored in contiguous memory locations.
Arrays can be of any type, including primitive types (e.g., int, float, char, boolean) or reference types
(e.g., String, user-defined classes). One-Dimensional Arrays
One-Dimensional Arrays
Declaration
type[] arrayName;
type: The type of elements in the array.
arrayName: The name of the array variable.
Example: int month_days[];
Allocation
To allocate memory for the array, use the new keyword:
arrayName = new type[size];
type: The data type of array elements. size: The number of elements in the array.
Accessing Elements
Multidimensional Arrays
Multidimensional arrays are arrays of arrays. They can have two or more dimensions.
Declaration
To allocate memory for a multidimensional array, specify the size of each dimension:
arrayName = new type[rows][columns];
Accessing Elements
4. Assignment Operators
Purpose: Assign values to variables.
Operators: =, +=, -=, *=, /=, %=
o = : Simple assignment
o += : Add and assign
o -= : Subtract and assign
o *= : Multiply and assign
o /= : Divide and assign
o %= : Modulus and assign
5. Increment and Decrement Operators
Purpose: Increase or decrease a variable's value by 1.
Operators: ++, --
o ++ : Increment (prefix or postfix)
o -- : Decrement (prefix or postfix)
6. Bitwise Operators
Purpose: Perform bit-level operations.
Operators: &, |, ^, ~, <<, >>, >>>
o & : Bitwise AND
o | : Bitwise OR
o ^ : Bitwise XOR
o ~ : Bitwise NOT
o << : Left shift
o >> : Right shift
o >>>: Unsigned right shift
8. Instanceof Operator
Purpose: Test whether an object is an instance of a specific class or subclass.
Operator: instanceof
Example:
public class SimpleOperatorDemo {
public static void main(String[] args) {
// Arithmetic Operators
int a = 15, b = 4;
System.out.println("a + b = " + (a + b)); // Addition
System.out.println("a - b = " + (a - b)); // Subtraction
System.out.println("a * b = " + (a * b)); // Multiplication
System.out.println("a / b = " + (a / b)); // Division
System.out.println("a % b = " + (a % b)); // Modulus
// Relational Operators
System.out.println("a == b: " + (a == b)); // Equal to
System.out.println("a != b: " + (a != b)); // Not equal to
System.out.println("a > b: " + (a > b)); // Greater than
System.out.println("a < b: " + (a < b)); // Less than
// Logical Operators
boolean x = true, y = false;
System.out.println("x && y: " + (x && y)); // AND
System.out.println("x || y: " + (x || y)); // OR
System.out.println("!x: " + (!x)); // NOT
// Assignment Operator
int c = 10;
c += 5; // Equivalent to c = c + 5
System.out.println("c += 5: " + c); // 15
// Increment Operator
int d = 5;
System.out.println("d++: " + d++); // 5 (then d becomes 6)
System.out.println("++d: " + ++d); // 7
}
}
1.8 control statements
1. Control Statements
a. Conditional Statements
Type conversion and casting are fundamental concepts in Java that enable the assignment of values
between variables of different types. Here's an overview of automatic type conversions, explicit casting,
and type promotion rules:
Compatible Types: Numeric types (e.g., int, long, float) can be automatically converted if the
destination type can accommodate the value of the source type.
No Automatic Conversion: There is no automatic conversion between numeric types and char or
boolean. For example, you cannot directly assign an int to a char or boolean variable without a cast.
int i = 10;
long l = i; // int to long (widening conversion)
float f = 3.14f;
double d = f; // float to double (widening conversion)
2. Casting Incompatible Types
When automatic conversion is not possible, explicit casting is required. Casting is used to convert a
value from one type to another, especially when the destination type is smaller than the source type
(narrowing conversion).
Floating-Point to Integer: Converting from float or double to an integer type truncates the
fractional part.
Overflow: If the value exceeds the range of the target type, it wraps around according to the
type's range.
Promotion Rules:
1. byte, short, char → Promoted to int.
2. int → Promoted to long if combined with a long.
3. long → Promoted to float if combined with a float.
4. float → Promoted to double if combined with a double.
byte a = 40;
byte b = 50;
byte c = 100;
int d = a * b / c; // byte to int promotion in expression
System.out.println(d); // Output: 20
Compilation Error Example:
byte b = 50;
b = b * 2; // Error! b * 2 results in int, cannot assign to byte
b = (byte)(b * 2); // Correct, explicit cast to byte
1.9 Simple java program
A class is declared by use of the class keyword. The classes that have been used up to this point
are actually very limited examples of its complete form. Classes can (and usually do) get much more
complex A simplified general form of a class definition is shown here:
class classname
{
type instance-variable1; // ...
type instance-variableN;
type methodname1(parameter-list)
{
// body of method
}
type methodname2(parameter-list)
{
// body of method
}
// ...
type methodnameN(parameter-list)
{
// body of method
}
}
1.10 Constructors- Methods
1. Introduction to Constructors:
// Parameterized constructor
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
}
Usage in Main Method:
public class BoxDemo {
public static void main(String[] args) {
Box mybox1 = new Box(10, 20, 15);
Box mybox2 = new Box(3, 6, 9);
System.out.println("Volume of mybox1: " + mybox1.volume());
System.out.println("Volume of mybox2: " + mybox2.volume());
}
}
4. The this Keyword:
Definition: this is a reference variable that refers to the current object within an instance
method or constructor.
Usage:
o Resolves naming conflicts between instance variables and method parameters.
o Accesses instance variables and methods from within the class.
Example:
class Box {
double width;
double height;
double depth;
// Default constructor
Box() {
width = 1;
height = 1;
depth = 1;
}
// Parameterized constructor
Box(double w, double h, double d) {
width = w;
height = h;
depth = d;
}
}
6. Garbage Collection:
Definition: Automatic memory management process that reclaims memory used by objects that
are no longer referenced.
Key Points:
o Java handles garbage collection automatically, reducing the need for manual memory
management.
o Garbage collection occurs sporadically and is not directly controlled by the programmer.
7. The finalize() Method:
Definition: A method that can be overridden to define actions that should be performed before
an object is reclaimed by the garbage collector.
Usage:
o Typically used to release non-Java resources (e.g., file handles, network connections).
Syntax:
protected void finalize() {
// Cleanup code before garbage collection
}
1.11 Static block, Static Data, Static Method
1. Static Data (Static Variables):
Definition: Static variables, also known as class variables, are shared among all instances of a
class. They belong to the class rather than to any specific instance.
Characteristics:
o Declared with the static keyword.
o Initialized once, at the start of the execution.
o Accessible via the class name as well as through instances of the class.
Usage:
o Used to store data common to all objects of the class.
Example:
class Counter {
static int count = 0; // static variable
Counter() {
count++; // Increment count whenever a new object is created
}
}
static {
value = 10; // Initialize static variable
System.out.println("Static block executed");
}
}
1. String Class:
Definition: The String class represents a sequence of characters and is one of the most
commonly used classes in Java. Strings are immutable, meaning once a String object is created,
it cannot be modified.
Characteristics:
o Immutable: Any modification creates a new String object.
o Defined in: java.lang package.
o Syntax: String str = "Hello";
Key Methods:
o length(): Returns the length of the string.
String s = "Hello";
int len = s.length(); // len = 5
o indexOf(String str): Returns the index of the first occurrence of the specified
substring.
o replace(char oldChar, char newChar): Returns a new string where all occurrences
of the specified character are replaced.
o equals(Object obj): Compares the string with the specified object for equality.
Example:
2. StringBuffer Class:
sb.delete(4, 14);
System.out.println("After delete: " + sb);
sb.reverse();
System.out.println("After reverse: " + sb);
sb.replace(0, 5, "Python");
System.out.println("After replace: " + sb);