Module 1 Introduction to Java
Module 1 Introduction to Java
● Platform Independent: Java is famous for its Write Once, Run Anywhere (WORA) feature.
This means we can write our Java code once, and it will run on any device or operating
system without changing anything.
● Object-Oriented: Java follows the object-oriented programming. This makes code clean and
reusable.
● Security: Java does not support pointers, it includes built-in protections to keep our programs
secure from common problems like memory leakage.
● Multithreading: Java programs can do many things at the same time using multiple threads.
This is useful for handling complex tasks like processing transactions.
● Just-In-Time (JIT) Compiler: Java uses a JIT compiler. It improves performance by converting
the bytecode into machine readable code at the time of execution.
Runtime Environment (Command Line & IDE)
● The most basic commands for using Java on the command line are javac and
java;
○ javac is used to compile Java source code,
○ java is used to run Java stand-alone applications.
javac Interest2.java
java Interest2
IDEs and Eclipse
● A programming language
● An API specification
● A virtual machine specification
A Java compiler is a program that takes the text file work of a developer and compiles it into a
platform-independent Java file. Java compilers include the Java Programming Language Compiler
(javac), the GNU Compiler for Java (GCJ), the Eclipse Compiler for Java (ECJ), and Jikes.
Compilation Process:
javac: The Java compiler (javac) takes these .java files as input.
Bytecode: The compiler translates the source code into platform-independent bytecode, stored
in .class files.
JVM: The JVM then loads, verifies, and executes this bytecode.
Java Virtual Machine
● JVM (Java Virtual Machine) runs Java applications as a run-time engine.
● JVM is the one that calls the main method present in a Java code. JVM is a part of JRE (Java
Runtime Environment).
● Java applications are called WORA (Write Once Run Anywhere). This means a programmer
can develop Java code on one system and expect it to run on any other Java-enabled system
without any adjustments. This is all possible because of the JVM.
● When we compile a .java file, .class files (containing byte-code) with the same class names
present in the .java file are generated by the Java compiler.
● This .class file goes through various steps when we run it. These steps together describe the
whole JVM.
● Loads bytecode
● Verifies bytecode
● Executes bytecode
● Provides a runtime environment to support various applications
JVM Architecture
● ClassLoader
● Memory area / Runtime memory
● Execution engine
1. Class Loader Subsystem
● Loading:
a. JVM loads the compiled .class files to run Java applications, and to perform this action; a JVM relies on its
ClassLoader.
b. ClassLoader reads the .class file generated by the javac command and extracts core information.
c. Then it stores this information in the Method Area.
d. The ClassLoader allows you to retrieve information such as classes, their names, variables, and
methods.Classloaders employ lazy-loading and cache to make class loading efficient and effective.
● Linking :
○ Verification: This step ensures that the .class file is correct. Then it checks whether
a valid compiler did the file’s creation and generation. And, if the verification fails,
we get a java.lang.VerifyError exception and the linking process comes to a halt.
○ Preparation: JVM allocates memory to static Class variables and initializes it to
default values.
○ Resolution: It is the process of replacing symbolic references with new ones and
involves searching in the method area to locate a referenced entity.
● Initialization
○ The final step in the class-loading process is where the static variables are
assigned their defined values, and static blocks are executed.
2. Memory area / Runtime memory
● Method area: In the method area, all class level information like class name, immediate parent class name,
methods and variables information etc. are stored, including static variables. There is only one method area
per JVM, and it is a shared resource.
● Heap area: Information of all objects is stored in the heap area. There is also one Heap Area per JVM. It is
also a shared resource.
● Stack area: For every thread, JVM creates one run-time stack which is stored here. Every block of this stack
is called activation record/stack frame which stores methods calls. All local variables of that method are
stored in their corresponding frame. After a thread terminates, its run-time stack will be destroyed by JVM.
It is not a shared resource.
● PC Registers: Store address of current execution instruction of a thread. Obviously, each thread has
separate PC Registers.
● Native method stacks: For every thread, a separate native stack is created. It stores native method
information.
3. Execution engine
● It is the core area of Java Virtual Machine. The execution engine can communicate with
different memory areas in JVM.
● Every thread in a Java application is an instance of the execution engine of the virtual
machine.
● The execution engine executes the byte code assigned to runtime data areas via the
ClassLoader. It consists of three main components:
a. Interpreter
b. JIT Compiler
c. Garbage Collector
The execution of a Java program
The first step is to write the Java program in a text editor or an Integrated Development Environment (IDE) and save
it with a .java extension (e.g., MyProgram.java).
2. Compilation:
The Java compiler, javac, translates the .java source code into bytecode, which is a platform-independent
intermediate representation. This bytecode is stored in a .class file (e.g., MyProgram.class).
3. Loading and Verification:
The Java Virtual Machine (JVM) loads the .class file into memory using a ClassLoader.
Before execution, the Bytecode Verifier checks the bytecode for security and integrity to ensure
it adheres to Java's rules and does not pose a threat.
4. Execution:
The JVM executes the bytecode. This can occur in two primary ways:
Interpretation: An interpreter within the JVM executes the bytecode instructions line by line. This is
generally slower but simpler.
Just-In-Time (JIT) Compilation: For frequently executed code sections (hot spots), the JIT
compiler translates the bytecode into native machine code specific to the underlying operating
system and hardware. This compiled machine code is then cached and reused for subsequent
executions, significantly improving performance.
5. Running the Program:
To run the compiled Java program, the java command is used, followed by the name
of the class containing the main method (the program's entry point).
The JVM then begins execution from the main method, interacting with the operating
system to produce the program's output, whether it's on the console or a graphical user
interface.
Java Syntax
Main.java
public class Main {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
Java Data Types
boolean Data Type
The boolean data type represents a logical value that can be either true or false. Conceptually, it represents a single
bit of information, but the actual size used by the virtual machine is implementation-dependent and typically at least
one byte (eight bits) in practice. Values of the boolean type are not implicitly or explicitly converted to any other type
using casts. However, programmers can write conversion code if needed.
Syntax:
}
boolean
} booleanVar;
System.out.println("Is fish tasty? " + b2);
System.out.println("Is Java fun? " + b1);
Size : Virtual machine
boolean b2dependent
= false; (typically 1 byte, 8 bits)
boolean b1 = true;
Example: Thisstatic
public example, demonstrating
void how to
main(String[] use boolean
args) { data type to display true/false values.
public class Geeks {
// Demonstrating boolean data type
byte Data Type
The byte data type is an 8-bit signed two's complement integer. The byte data type is useful for saving memory in
large arrays.
Syntax:
byte byteVar;
}
}
System.out.println("Temperature: " + t);
Size : 1 byte (8 bits)
System.out.println("Age: " + a);
byte t = -10;
Example: This
byteexample,
a = 25;demonstrating how to use byte data type to display small integer values.
public static void main(String[] args) {
public class Geeks {
// Demonstrating byte data type
short Data Type
The short data type is a 16-bit signed two's complement integer. Similar to byte, a short is used when memory
savings matter, especially in large arrays where space is constrained.
Syntax:
short shortVar;
}
}
System.out.println("Temperature: " + t);
Size : 2 bytes (16 bits)
System.out.println("Number of Students: " + num);
short t = -200;
Example: This
shortexample,
num = demonstrates
1000; how to use short data type to store moderately small integer value.
public static void main(String[] args) {
public class Geeks {
// Demonstrating short data types
int Data Type
Size
} : 4 bytes ( 32 bits )
}
Remember: In Java SE 8 and later, we can "use
System.out.println("Distance: + the
d);int data type to represent an unsigned 32-bit integer, which
System.out.println("Population: " + p);
has a value in the range [0, 2 32 -1]. Use the Integer class to use the int data type as an unsigned integer.
int d = 150000000;
int p = 2000000;
Example: Thisstatic
public examplevoid
demonstrates how to args)
main(String[] use int {data type to display larger integer values.
public class Geeks {
// Demonstrating int data types
long Data Type
The long data type is a 64-bit signed two's complement integer. It is used when an int is not large enough to hold a
value, offering a much broader range.
Syntax: long longVar; Size : 8 bytes (64 bits)
Remember: In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which
}has a minimum value of 0 and a maximum value of 2 64 -1. The Long class also contains methods like
}
comparing Unsigned, divide Unsigned, Year
System.out.println("Light etc to Distance:
support arithmetic
" + l);operations for unsigned long.
System.out.println("World Population: " + w);
Example: Thisl
long
long wexample demonstrates how to use long data type to store large integer value.
= 9460730472580800L;
= 7800000000L;
public static void main(String[] args) {
public class Geeks {
// Demonstrating long data type
float Data Type
The float data type is a single-precision 32-bit IEEE 754 floating-point. Use a float (instead of double) if you need to
save memory in large arrays of floating-point numbers. The size of the float data type is 4 bytes (32 bits).
Syntax:
float floatVar;
}
}
System.out.println("Gravity: " + gravity);
Size : 4 bytes (32 bits)
System.out.println("Value of Pi: " + pi);
float gravity = 9.81f;
Example: This
floatexample demonstrates how to use float data type to store decimal value.
pi = 3.14f;
public static void main(String[] args) {
public class Geeks {
// Demonstrating float data type
char Data Type
The char data type is a single 16-bit Unicode character with the size of 2 bytes (16 bits).
Syntax:
char charVar;
}
}
System.out.println("Symbol: " + s);
Size : 2 bytes (16 bits)
System.out.println("Grade: " + g);
char s = '$';
Example: This
charexample, demonstrates how to use char data type to store individual characters.
g = 'A';
public static void main(String[] args) {
public class Geeks{
// Demonstrating char data type
Strings
Strings are defined as an array of characters. The difference between a character array and a string in Java is, that the
string is designed to hold a sequence of characters in a single variable whereas, a character array is a collection of
separate char-type entities. Unlike C/C++, Java strings are not terminated with a null character.
Syntax: Declaring a string
}
<String_Type>
} <string_variable> = “<sequence_of_string>”;
System.out.println("Message: " + m);
System.out.println("Name: " + n);
String m = "Hello, World!";
Example: This example
String demonstrates how to use string variables to store and display text values.
n = "Geek1";
public static void main(String[] args) {
public class Geeks {
// Demonstrating String data type
Array
An Array is a group of like-typed variables that are referred to by a common name. Arrays in Java work differently
than they do in C/C++.
Casting in Java is the process of converting a value of one data type into another. It can be categorized into two
main types:
● Implicit Casting (Widening Conversion): This occurs automatically when converting a smaller data type to a larger data
type, where no data loss is possible. For example, converting an int to a long or a float to a double.
● Explicit Casting (Narrowing Conversion): This requires a manual cast operator () when converting a larger data type to
a smaller data type, as data loss is possible. For example, converting a double to an int.
Autoboxing and Unboxing in Java
Autoboxing and unboxing are features introduced in Java 5 that simplify the conversion between primitive data types
and their corresponding wrapper classes.
● Autoboxing: This is the automatic conversion of a primitive data type into its corresponding wrapper class object. For
example, an int is automatically converted to an Integer object.
● Unboxing: This is the automatic conversion of a wrapper class object into its corresponding primitive data type. For example,
an Integer object is automatically converted to an int.
Key Difference:
While both casting and autoboxing/unboxing involve type conversions, the fundamental distinction lies in their scope:
Casting is a general mechanism for converting between various data types, including primitives, objects, and even between
class hierarchies (upcasting/downcasting). It can be explicit or implicit.
Autoboxing/Unboxing specifically addresses the automatic conversion between primitive types and their respective wrapper
classes, simplifying code and reducing the need for manual conversions.
Java Operators
Unary Operators need only one operand. They are used to increment, decrement, or negate a value.
● - , Negates the value.
● + , Indicates a positive value (automatically converts byte, char, or short to int).
● ++ , Increments by 1.
○ Post-Increment: Uses value first, then increments.
○ Pre-Increment: Increments first, then uses value.
● -- , Decrements by 1.
○ Post-Decrement: Uses value first, then decrements.
○ Pre-Decrement: Decrements first, then uses value.
● ! , Inverts a boolean value.
Ternary operator
The Ternary Operator is a shorthand version of the if-else statement. It has three
operands and hence the name Ternary. The general format is,
condition ? if true : if false
public class Geeks {
Bitwise Operators are used to perform the manipulation of individual bits of a number
and with any of the integer types. They are used when performing update and query
operations of the Binary indexed trees.
● & (Bitwise AND): returns bit-by-bit AND of input values.
Shift Operators are used to shift the bits of a number left or right, thereby multiplying or
dividing the number by two, respectively. They can be used when we have to multiply or divide
a number by two. The general format ,
number shift_op number_of_places_to_shift;
● << (Left shift): Shifts bits left, filling 0s (multiplies by a power of two).
● >> (Signed right shift): Shifts bits right, filling 0s (divides by a power of two), with the
class ifExample{
public static void main(String args[]){
int a = 10;
if( a > 5){
System.out.println("If block executed");
}
}
}
if(condition){
//code for if statement
}
else{
//code for else statement.
}
class ifElseExample{
public static void main(String args[]){
int a = 10;
if( a%2 == 0){
System.out.println("Number is even.");
}
else{
System.out.println("Number is odd.");
}
}
}
if(condition1){
//code to be executed for condition1
}
if(condition2){
//code to be executed for condition2
class NestedIfExample {
} public static void main(String[] args) {
int num1 = 10, num2 = 5, num3 = 20, largestNumber;
if (num1 >= num2) {
if (num1 >= num3) {
largestNumber = num1;
} else {
largestNumber = num3;
}
} else {
if (num2 >= num3) {
largestNumber = num2;
} else {
largestNumber = num3;
}
}
System.out.println("Largest number is: " + largestNumber);
}
}
if(condition1){
//statement1;
} class IfElseLadder {
else if(condition2){
public static void main(String[] args) {
//statement2;
}
else if(condition3){
int examscore = 75;
//statement3; char grade;
}
......... if(examscore >= 90) {
......... grade = 'A';
......... } else if (examscore >= 80) {
else{ grade = 'B';
//default statement; } else if(examscore >= 70) {
} grade = 'C';
} else if(examscore >= 60) {
grade = 'D';
} else {
grade = 'F';
}
System.out.println("Grade is = " + grade);
}
}
switch(expression){ class SwitchStatement{
case value1: public static void main(String args[]){
//statement sequence for(int i = 0; i<6; i++)
break; switch(i){
case value2: case 0:
//statement sequence System.out.println("i is zero.");
break; break;
....... case 1:
....... System.out.println("i is one.");
....... break;
case valueN: case 2:
//statement sequence System.out.println("i is two.");
break; break;
default: case 3:
//default statement sequence System.out.println("i is three.");
} break;
default:
System.out.println("i is greater than 3.");
}
}
}
while(boolean condition){
//body of the loop.
}
class WhileLoop{
public static void main(String args[]){
System.out.println("The values from 1 to 10 is: ");
int num = 1; // initialization.
// condition checking.
while(num <= 10){
System.out.println(num);
num++; // updation.
}
}
}
do{
// body of the loop.
}
while(condition);
class DoWhileLoop{
public static void main(String args[]){
System.out.println("The values from 1 to 10 is: ");
int num = 1; // initialization.
do{
System.out.println(num);
num++; // updation.
}
// condition checking.
while(num <= 10);
}
}
for(initialization; condition; incr/decr){
//body of the loop.
}
class ForLoop{
public static void main(String args[]){
System.out.println("The values from 1 to 10 is: ");
String[] cars;
● Modifier: It specifies the method's access level (e.g., public, private, protected, or default).
● Return Type: The type of value returned, or void if no value is returned.
● Method Name: It follows Java naming conventions; it should start with a lowercase verb and use camel
case for multiple words.
● Parameters: A list of input values (optional). Empty parentheses are used if no parameters are needed.
● Exception List: The exceptions the method might throw (optional).
● Method Body: It contains the logic to be executed (optional in the case of abstract methods).
Types of Methods in Java
1. Predefined Method
Predefined methods are the method that is already defined in the Java class libraries. It is also known as the
standard library method or built-in method. for example random() method which is present in the Math class and we
can call it using the ClassName.methodName() as shown in the below example.
Example:
Math.random() // returns random value
Math.PI() // return pi value
2. User-defined Method
The method written by the user or programmer is known as a user-defined method. These methods are modified
according to the requirement.
Example:
sayHello // user define method created above in the article
Greet()
setName()
Parameters and Arguments
public class Main {
static void myMethod(String fname) {
System.out.println(fname + " Refsnes");
}
public static void main(String[] args) {
myMethod("Liam");
myMethod("Jenny");
myMethod("Anja");
}
}
Method Overloading : With method overloading, multiple methods can have the same name
with different parameters:
int myMethod(int x)
float myMethod(float x)
double myMethod(double x, double y)
}
Command-Line Arguments
Command-line arguments are passed to the main method of a Java program when it is executed. These
arguments are stored in the String[] args array.
Output:
Number of arguments: 3
Argument 0: arg1
Argument 1: arg2
Argument 2: arg3
Variable-Length Arguments (Varargs)
Variable-length arguments allow a method to accept zero or more arguments of the same type. This is achieved using the ...
syntax.Variable Arguments (Varargs) write methods that can take any number of inputs, which simply means we
do not have to create more methods for different numbers of parameters. This concept was introduced in Java 5
to make coding easier. Instead of passing arrays or multiple methods, we can simply use one method, and it will
handle all the test cases.