Overview of Java:
Java is a popular programming language that was created by a company called Sun
Microsystems in the mid-1990s. Now, it’s owned by another company called Oracle. Java is
famous because it works on many different types of computers, supports object-oriented
programming, and is very reliable. People use Java to make different types of software like
computer programs, phone apps, websites, and business tools.
Main Features of Java:
1. Works on All Platforms (Platform Independence):
One of the best things about Java is that you can run it on any computer that has a
program called Java Virtual Machine (JVM). When you write Java code, it gets turned
into something called bytecode. This bytecode can run on any device that has a JVM,
no matter what kind of computer it is.
2. Object-Oriented Programming (OOP):
Java uses a style called object-oriented programming. This means you can create
"objects" to represent real-life things, like a Car or a Student. You can organize your
code better and reuse parts of it. Java uses ideas like classes (blueprints for objects),
objects, inheritance (passing features from one class to another), and polymorphism
(using one method in different ways).
3. Easy to Read and Write (Simple Syntax):
Java’s code is easy to understand and write, especially if you already know C or C++
(older languages). The rules for writing Java code help keep it clean and well-
organized, which makes it easier to work with.
4. Reliable and Manages Memory Automatically (Robustness):
Java is made to avoid errors as much as possible. It has tools like exception handling
(which catches errors when they happen) and automatic memory management, also
called garbage collection. This means Java takes care of memory by itself, so you
don’t have to worry about freeing up space when you're done with something.
5. Huge Built-In Library (Standard Library):
Java gives you a big collection of ready-made tools, called the standard library. This
includes stuff for reading input, saving files, using data structures (like arrays or lists),
working with the internet, running multiple tasks at once, and much more. These
built-in tools help save you a lot of time and effort when coding.
JVM, JRE, and JDK
1. JVM (Java Virtual Machine):
The JVM is the part of Java that actually runs your code. When you compile Java, it
turns into “bytecode,” and the JVM takes that bytecode and either translates or just-
in-time compiles it into the computer’s own machine code. It also looks after
memory (so your program doesn’t crash), checks security rules, and does other
behind-the-scenes work. Because every platform has its own JVM, the same
bytecode runs anywhere.
2. JRE (Java Runtime Environment):
The JRE is basically the JVM plus all the extra libraries and files you need to run Java
apps. It’s everything an end user needs to open and use a Java program—but it
doesn’t include the tools to write or compile new Java code.
3. JDK (Java Development Kit):
The JDK is the full toolkit for creating Java applications. It bundles the JRE (so you can
run what you build), plus compilers, debuggers, and other tools you use to write,
test, and debug Java programs. Developers install the JDK when they want to build
Java software.
Parts of the First Java Program
Let’s understand what these common words in a basic Java program mean: class, public,
static, void, main, String[], and System.out.println().
class
The class keyword is used when you want to create a class in Java. A class is like a
blueprint for making objects (like a template for creating something).
public
public is a keyword that controls visibility. If something is marked as public, it means
anyone can see or use it, from anywhere in the program.
static
static means that a method belongs to the class itself, not to objects made from the
class. If a method is static, you don’t have to create an object to use it. The main()
method is static because the JVM (Java Virtual Machine) needs to run it without
creating any object first. This helps save memory too.
void
void is the return type of a method. It means the method does not give back (return)
any value.
main
The main method is where the program starts running. It’s the entry point that the
JVM looks for when the program begins.
String[] args (or String args[])
This is used when we want to give input to the program from the command line.
We’ll learn more about this in a later section.
System.out.println()
This is used to print something on the screen. System is a built-in class, out is an
object that helps with output, and println() is a method that prints text followed by a
new line. We’ll look deeper into how this works later on.
JVM as an Interpreter and Emulator
The JVM (Java Virtual Machine) can act like both an interpreter and an emulator, depending
on how it runs Java bytecode. Let’s break this down:
1. JVM as an Interpreter:
The JVM can read and run Java bytecode one instruction at a time, like reading steps from a
recipe and doing them on the spot. This is called interpreting, and it happens while the
program is running.
When it interprets the code, it doesn’t change it into machine language first—it just reads
and runs it directly. This helps Java programs work on any computer, because the JVM
handles the bytecode the same way, no matter what system it’s on.
The interpreter mostly handles code that’s not used often or hasn’t been converted into
machine code by the JIT (Just-In-Time) compiler yet.
2. JVM as an Emulator:
The JVM can also be thought of as an emulator because it acts like a fake computer system
where Java programs run. It pretends to be a real machine and gives the program everything
it needs to work properly.
The JVM hides the details of the actual computer it's running on and provides a safe and
stable place for Java programs. It emulates (copies) things like memory handling, managing
stacks (where data is stored temporarily), managing threads (for multitasking), and doing
input/output operations.
This emulation makes sure that Java programs run the same way on any computer, even if
the actual hardware and operating system are different.
Class File Format
A class file in Java is a file that stores the compiled code (called bytecode) that the JVM can
understand and run. It follows a specific format that the JVM knows how to read. Here's a
breakdown:
1. Magic Number and Version:
Every class file starts with a special 4-byte code called the magic number, which
shows it’s a valid class file. After that, it has version numbers (major and minor) that
show which version of Java the file was compiled with.
2. Constant Pool:
This section stores constant values that the class needs, like strings, names of
methods or variables, and class names.
It works like a list, and each item in the list has a tag showing what type it is (e.g.,
string, number) and what the actual value is.
3. Access Flags and Class Info:
Access flags tell what kind of class it is (like public, final, or abstract).
Class info tells the full name of the class, the name of the class it extends
(superclass), and any interfaces it implements.
4. Fields and Methods:
o Fields are the variables in the class. This part shows their names, types, and
access level.
o Methods are the functions in the class. It includes method names, return
types, parameters, access flags, and their bytecode instructions.
5. Attributes:
These give extra details about the class, fields, or methods.
Examples include the source file name, which line numbers go with which
instructions, what exceptions might be thrown, and annotations.
The class file is platform-independent, meaning it can run on any device with a JVM. Its
structure is defined by the Java Virtual Machine Specification and can change as Java gets
updated.
Bytecode Verification
Before running the bytecode, the JVM checks it using a process called verification. This helps
avoid bugs or harmful code from being executed. Here's what it checks:
1. Bytecode Structure:
It checks if the bytecode follows the rules — like using correct instructions, the right
kind of values, valid if/else blocks, and exception handling.
2. Type Safety:
It makes sure that the data types used are correct. For example, you don’t
accidentally try to add a string to an integer.
3. Memory Safety:
It checks for problems like accessing memory in a wrong way or causing bugs that
could crash the program or make it unsafe.
4. Stack Integrity:
The JVM uses a stack for temporary values during method calls. This step checks that
push/pop operations are done properly and the stack doesn’t get messed up.
Verification helps the JVM trust the bytecode, which is very important, especially if the code
is coming from an outside source (like downloading from the internet).
Class Area (Method Area)
This is a part of memory in the JVM where all the class-related information is stored. It is
shared by all threads and created when the JVM starts. Here's what it contains:
1. Class Structures:
Info about all the classes and interfaces loaded into the JVM — including names,
parent class names, interfaces, variables, methods, and more.
2. Runtime Constant Pool:
This is the actual in-memory version of the constant pool, used while the program
runs. It stores references to strings, numbers, method names, etc.
3. Method Bytecode:
The actual bytecode for methods (the instructions) is stored here. The JVM runs or
compiles this bytecode.
4. Static Variables:
These are variables that belong to the class, not the objects. They are stored here
and shared by all instances of the class.
The Class Area makes it easy for different parts of a program to share class data and is
cleaned up by the garbage collector when no longer needed.
Java Stack
The Java Stack is used when methods are called and to store local variables. Here's how it
works:
1. Stack Frames:
Every time a method runs, a new stack frame is created. It keeps local variables,
parameters, return addresses, and results.
2. LIFO (Last In, First Out):
The last thing added is the first to be removed. When a method ends, its frame is
removed from the stack.
3. Memory Management:
The JVM automatically handles the memory for the stack. It adds and removes
frames as methods are called and completed. The stack is small but fast.
4. One Stack per Thread:
Each thread in Java has its own stack, so multiple methods in different threads don’t
interfere with each other.
The Java Stack is great for quick method calls and temporary values, but it has limited
memory compared to the heap.
Java Heap
The Java Heap is the part of memory where objects and arrays are stored. It allows dynamic
memory use during the program’s execution.
1. Object Storage:
When you use new to create an object or array, it’s stored in the heap. It stays there
until it’s no longer needed.
2. Dynamic Memory:
You can create and delete objects at runtime. This gives you flexibility to manage
memory as your program runs.
3. Garbage Collection:
The JVM automatically removes objects that are no longer used using garbage
collection.
4. Shared by All Threads:
All threads in the program can access the same heap memory and the objects inside
it.
The Java Heap is large and flexible, but it also needs more management, which is handled by
the garbage collector.
Garbage Collection
Garbage Collection (GC) is how Java automatically frees up memory by removing objects
that are no longer needed. Here’s how it works:
1. Object Lifetimes:
GC checks which objects are no longer being used by any part of the program. These
are marked as garbage.
2. Mark and Sweep:
A common method where the JVM first marks all the objects still in use, and then
sweeps (deletes) the unmarked ones to free memory.
3. Stop-The-World:
During garbage collection, Java may pause all program threads temporarily to clean
up memory. This is called a stop-the-world event.
4. Generational Collection:
The heap is split into generations (like young and old) based on how long objects
have been around. Java focuses on collecting young objects more often, as they are
more likely to be unused.
Garbage Collection helps developers by managing memory automatically, reducing bugs
like memory leaks and improving program performance.
Security Promises of the JVM
The Java Virtual Machine (JVM) is designed with security in mind. It ensures that Java
programs behave safely and don’t do harmful things, even if they come from unknown
sources. Here are the main safety promises made by the JVM:
1. Each object is created once before it's used.
This means no object is used without being properly made.
2. Each object belongs to only one class for its whole life.
Once an object is created as part of a class, it stays that way forever.
3. Private methods or fields are only used inside their own class.
No outside code can access them.
4. Protected fields or methods are used only by code that helps implement the class.
This includes subclasses or classes in the same package.
5. Local variables are always initialized before they’re used.
You can’t use a variable before giving it a value.
6. Fields are also initialized before use.
Just like variables, fields (class-level variables) are never used uninitialized.
7. Stack overflows or underflows cannot happen.
The JVM prevents operations that would cause the stack to break.
8. Arrays cannot be accessed outside their bounds.
You can’t read or write past the beginning or end of an array.
9. Array lengths cannot be changed once the array is made.
Arrays are fixed in size after creation.
These features help the JVM provide a safe environment for running Java programs, even if
the code is from untrusted sources.
Security Architecture of the JVM
The JVM's security architecture is like a shield — it is made of multiple layers and tools that
work together to protect Java applications from doing anything unsafe. Here's how it works:
1. Security Manager
This is a key component that controls what code is allowed to do.
It can stop a program from reading or writing files, opening network connections, or
using unsafe features — unless permission is explicitly granted.
These rules are written in a security policy file, and the JVM uses them to allow or
block actions.
2. Security Providers
These are external modules that add cryptographic features like encryption,
decryption, digital signatures, and random number generation.
They follow special frameworks like Java Cryptography Architecture (JCA) and Java
Cryptography Extension (JCE).
Developers can choose or add custom providers for advanced security.
3. Access Control
This feature makes sure only allowed parts of the program can access sensitive
resources like files, networks, or system settings.
For example, a browser applet should not be able to read your local files — and
access control makes sure it can’t.
4. Class Loading and Sandboxing
Class loading ensures that classes are loaded only from trusted sources.
Before a class runs, it’s verified to be safe.
Sandboxing means running untrusted code in a controlled environment where it
can’t harm the system.
o It can't access files, devices, or sensitive data unless given permission.
5. Secure Communication
The JVM supports safe communication over the internet using protocols like HTTPS
and SSL/TLS.
These protect data during transmission, ensuring privacy and preventing tampering.
Java also offers cryptographic tools (via APIs) for secure messaging and
authentication.
Security Policy in the JVM
The security policy is a file that contains rules about what Java applications are allowed to
do. It includes:
Permissions (like file read/write, network access, etc.)
Restrictions (what actions are not allowed)
When the JVM starts, it reads this file and uses it to enforce access control. This allows
developers or system administrators to define the security behavior of Java applications
easily.
Sandbox Model in JVM
The sandbox model in Java is a security mechanism that protects your system from
untrusted or potentially harmful code — especially code downloaded from the internet like
applets.
It creates a safe, restricted environment (a "sandbox") where this untrusted code can run
without accessing or harming the system.
🔑 Key Features of the Sandbox Model:
1. Isolation
Untrusted code runs in a separate and restricted area.
It can’t touch system resources (like files, networks, or devices).
This keeps your operating system and other applications safe and unaffected.
2. Access Control
The sandbox uses access control rules to decide what the code can and cannot do.
For example:
o ✅ Allowed: Basic calculations or UI display
o ❌ Denied: Reading your files or accessing the internet (unless permitted)
3. Security Manager
Acts like a watchdog or gatekeeper.
It checks every action the untrusted code tries to perform.
If the action is not allowed by the security policy, it blocks it.
4. Security Policies
These are rules written in a policy file.
They define:
o What files or folders can be read/written
o Whether network access is allowed
o Which system settings can be read
The Security Manager uses these policies to allow or deny actions.
5. Bytecode Verification
Before any code runs, the JVM verifies its bytecode to make sure:
o It follows Java’s safety rules (e.g., no invalid memory access)
o There are no malicious tricks hidden in the code
This step helps prevent attacks and ensures the code is well-formed.
✅ Summary:
The sandbox model in JVM:
Isolates untrusted code from the rest of the system
Uses the Security Manager and security policies to control what code can do
Protects users from harmful operations by verifying and restricting code behavior
Class Loaders and Security Aspects in Java
Class loaders in Java are responsible for loading classes into the JVM at runtime. In addition
to their functional role, they play a critical part in maintaining security by controlling how
and from where classes are loaded.
📚 1. Class Loading Hierarchy
Java uses a parent delegation model for class loading.
There are mainly three types of class loaders:
o Bootstrap Class Loader (loads core Java classes)
o Extension Class Loader (loads classes from ext directory)
o Application Class Loader (loads classes from the application’s classpath)
When loading a class, each loader first asks its parent to load the class.
This ensures that trusted system classes are loaded first, reducing the risk of
malicious class replacement.
🔐 2. Class Loading Isolation
Each class loader has its own namespace.
Even if two classes have the same name, if they are loaded by different class loaders,
they are treated as completely different types.
This isolation:
o Prevents one module from interfering with another
o Supports modularity and safe plugin architectures
🛡️ 3. Security Constraints
Class loaders enforce security by checking if classes are being loaded from trusted
sources.
They work with the Security Manager and security policy files to define:
o What classes can be loaded
o What resources (files, networks, system properties) the class can access
👮♂️ 4. Security Manager and Class Loaders
The Security Manager uses information about the class loader and its source (e.g.,
local file, remote JAR) to grant or deny permissions.
Example:
o A class loaded from the internet may be denied file system access
o A class from the local disk might be given more permissions
🧰 5. Custom Class Loaders
Developers can create custom class loaders to:
o Load classes in a special way
o Implement extra security checks
o Verify or modify bytecode before it is loaded
Useful in enterprise apps, plugin systems, or sandboxing untrusted code.