Sri Raghavendra Educational Institutions Society

Sri Krishna Institute of Technology

(Approved by AICTE, Affiliated to VTU, Karnataka)

Rahul Kumar

Assistant Professor

Your Profile Picture

Module-wise Course Notes

Click on any module title to expand the notes for that topic. The content is directly available here for easy access and searching.


An Overview of Java

Object-Oriented Programming (OOP): Java is fundamentally an object-oriented language. This means it organizes software design around data, or objects, rather than functions and logic. The main principles are Encapsulation, Inheritance, Polymorphism, and Abstraction.

A First Simple Program

Every Java application begins with a `main()` method. The `System.out.println()` method is used to print output to the console.

class Example {
    // A Java program begins with a call to main().
    public static void main(String[] args) {
        System.out.println("This is a simple Java program.");
    }
}
A Second Short Program

This example demonstrates declaring a variable and using it.

class Example2 {
    public static void main(String[] args) {
        int myVar; // declare a variable
        myVar = 1024; // assign it a value

        System.out.println("myVar contains " + myVar);
    }
}
Two Control Statements

The `if` statement allows for conditional execution, and the `for` loop allows for repeated execution.

// Demonstrate an if statement and a for loop.
class IfForExample {
    public static void main(String[] args) {
        int x, y;
        y = 20;

        // Loop from 0 to 9
        for(x = 0; x < 10; x++) {
            System.out.println("This is x: " + x);
            System.out.println("This is y: " + y);
            
            // An if statement inside the loop
            if (x == 5) {
                System.out.println("x has reached 5!");
            }
            
            y = y - 2;
        }
    }
}
Using Blocks of Code

A block of code is a group of two or more statements enclosed in curly braces `{}`. It creates a new local scope.

Lexical Issues

These are the low-level rules that define how a Java program is written. They include:

  • Whitespace: Java is a free-form language. Spaces, tabs, and newlines don't affect the code's meaning, but are used for readability.
  • Identifiers: Names given to classes, methods, and variables.
  • Literals: Constant values, like `100`, `19.7`, `'X'`, or `"Hello"`.
  • Comments: `//` for single-line, `/* ... */` for multi-line.
  • Separators: Characters like `()`, `{}`, `[]`, `;`, `,`, `.`.
  • Keywords: Reserved words like `public`, `class`, `int`, `for`, etc.
The Java Class Libraries

Java is powerful because of its extensive Application Programming Interface (API), also known as the class libraries. These are pre-written classes that provide a vast amount of functionality, such as I/O, networking, and data structures.

Data Types, Variables, and Arrays

Java Is a Strongly Typed Language: Every variable must have a declared type, and the compiler checks for type compatibility.

The Primitive Types
  • Integers: `byte` (8-bit), `short` (16-bit), `int` (32-bit), `long` (64-bit).
  • Floating-Point Types: `float` (32-bit), `double` (64-bit).
  • Characters: `char` (16-bit Unicode).
  • Booleans: `boolean` (represents `true` or `false`).
A Closer Look at Literals

Integer literals are `int` by default (e.g., `10`). To specify a `long`, append `L` (e.g., `10L`). Floating-point literals are `double` by default (e.g., `10.5`). To specify a `float`, append `F` (e.g., `10.5F`).

Variables

A variable is a named memory location. It's declared with a type and an identifier, like `int count;`.

Type Conversion and Casting

Casting allows you to convert a value from one type to another. It's required when converting from a larger type to a smaller type (a "narrowing conversion").

double d = 100.04;
long l = (long)d; // Explicit cast to long (loses fractional part)
int i = (int)l;   // Explicit cast to int
Automatic Type Promotion in Expressions

In an expression, Java automatically promotes smaller types (like `byte` and `short`) to `int` before the calculation is performed. If one operand is `long`, `float`, or `double`, the whole expression is promoted to that type.

Arrays

An array is a collection of a fixed number of elements of the same type. They are declared, created, and then initialized.

// Declare, create, and initialize a one-dimensional array
int[] monthDays = new int[12];
monthDays[0] = 31; // January
monthDays[1] = 28; // February
// ...and so on.

// A two-dimensional array
int[][] twoD = new int[4][5];
A Few Words About Strings

In Java, `String` is not a primitive type. It is a class. `String` objects are immutable, meaning once created, their contents cannot be changed.

Operators
  • Arithmetic Operators: `+`, `-`, `*`, `/`, `%` (modulus), `++` (increment), `--` (decrement).
  • The Bitwise Operators: Work on the individual bits of their operands. `&` (AND), `|` (OR), `^` (XOR), `~` (NOT), `>>` (right shift), `<<` (left shift), `>>>` (unsigned right shift).
  • Relational Operators: `==`, `!=`, `>`, `<`, `>=`, `<=`. They produce a `boolean` result.
  • Boolean Logical Operators: `&` (logical AND), `|` (logical OR), `^` (logical XOR), `||` (short-circuit OR), `&&` (short-circuit AND), `!` (logical NOT).
  • The Assignment Operator: The `=` operator. Compound assignments also exist, like `+=`, `-=`, `*=`, etc.
  • The `?` Operator: The ternary operator, a shorthand for an if-then-else statement. `variable = expression ? value_if_true : value_if_false;`
Operator Precedence

Determines the order in which operators are evaluated. For example, multiplication and division are performed before addition and subtraction.

Using Parentheses

Parentheses `()` are used to alter the normal precedence of operators. They raise the precedence of the operations within them. It's good practice to use them for clarity even when not strictly necessary.

Control Statements
  • Java’s Selection Statements:
    • `if`: Executes code if a condition is true. Can be followed by `else if` and `else`.
    • `switch`: Selects from a set of discrete values (cases). Works with `byte`, `short`, `char`, `int`, `enum`, and `String`.
  • Iteration Statements:
    • `while`: Repeats a block of code while a condition is true. The condition is checked at the start.
    • `do-while`: Repeats a block of code while a condition is true. The condition is checked at the end, so the loop always executes at least once.
    • `for`: A compact loop for iterating a specific number of times. Includes initialization, condition, and iteration expressions.
    • `for-each`: A special `for` loop for iterating over arrays or collections.
  • Jump Statements:
    • `break`: Exits a loop or a `switch` statement immediately.
    • `continue`: Skips the current iteration of a loop and proceeds to the next.
    • `return`: Exits from the current method.
// Example of switch and for-each loop
class ControlExample {
    public static void main(String[] args) {
        // Switch statement
        int month = 4;
        String monthString;
        switch (month) {
            case 1:  monthString = "January"; break;
            case 2:  monthString = "February"; break;
            case 3:  monthString = "March"; break;
            case 4:  monthString = "April"; break;
            default: monthString = "Invalid month"; break;
        }
        System.out.println(monthString);

        // For-each loop
        int[] nums = { 1, 2, 3, 4, 5 };
        int sum = 0;
        for(int x : nums) { // for each int x in nums
            sum += x;
        }
        System.out.println("Sum of nums is: " + sum);
    }
}

Introducing Classes

Class Fundamentals: A class is a template or blueprint for creating objects. It defines state (fields/variables) and behavior (methods).

Declaring Objects: You declare a variable of the class type, then use the `new` keyword to allocate memory and create an instance (an object).

Assigning Object Reference Variables: `Box myBox = new Box();` Here, `myBox` doesn't hold the object itself, but a reference (memory address) to the object.

Introducing Methods & Constructors

Methods: A method is a block of code that performs a specific task. It provides a way to access and manipulate an object's state.

Constructors: A special method that is called when an object is created. It's used to initialize the object's state. It has the same name as the class and no return type.

The `this` Keyword: Inside a method, `this` is a reference to the current object—the object whose method was called. It's often used to distinguish between instance variables and parameters with the same name.

class Box {
    double width;
    double height;
    
    // Constructor using 'this'
    Box(double width, double height) {
        this.width = width; // 'this.width' is the instance variable
        this.height = height; // 'width' is the parameter
    }

    // Method to calculate volume
    double volume() {
        return width * height;
    }
}
Garbage Collection and `finalize()`

Garbage Collection: The automatic process in Java for reclaiming the memory of objects that are no longer referenced. You do not need to manually deallocate memory.

The `finalize()` Method: This method is called by the garbage collector just before an object is reclaimed. **Note: `finalize()` is deprecated and its use is strongly discouraged.** Modern alternatives like `try-with-resources` should be used for resource management.

A Closer Look at Methods and Classes
  • Overloading Methods: Creating multiple methods with the same name but different parameters (either different number of parameters or different types).
  • Using Objects as Parameters: You can pass objects to methods just like any other data type.
  • Returning Objects: Methods can also return objects.
  • Recursion: A method that calls itself.
  • Introducing Access Control: Keywords that set the visibility of members. `public` (accessible everywhere), `private` (accessible only within its own class), `protected` (accessible within its package and by subclasses).
  • Understanding `static`: A `static` member belongs to the class itself, not to any single object instance. All objects of the class share the same static variable.
  • Introducing `final`: A `final` variable is a constant. A `final` method cannot be overridden. A `final` class cannot be inherited.
Inheritance

Inheritance: The process where one class (subclass) acquires the properties of another (superclass) using the `extends` keyword.

Using `super`: The `super` keyword is used to refer to the immediate superclass. It can be used to call the superclass's constructor (`super()`) or to call a superclass method (`super.methodName()`).

Method Overriding: A subclass provides a specific implementation of a method that is already defined in its superclass.

Dynamic Method Dispatch: The mechanism by which a call to an overridden method is resolved at runtime, rather than compile time. This is how polymorphism is implemented in Java.

Using Abstract Classes: A class declared with the `abstract` keyword cannot be instantiated. It can have abstract methods (methods without a body) that must be implemented by its concrete subclasses.

The `Object` Class: The root of the class hierarchy. Every class in Java is a direct or indirect subclass of `Object`.

// Superclass
abstract class Figure {
    double dim1;
    double dim2;
    Figure(double a, double b) { dim1 = a; dim2 = b; }
    // area is now an abstract method
    abstract double area();
}

// Subclass
class Rectangle extends Figure {
    Rectangle(double a, double b) {
        super(a, b); // call superclass constructor
    }
    // override area for rectangle
    double area() {
        System.out.println("Inside Area for Rectangle.");
        return dim1 * dim2;
    }
}

Packages and Interfaces

Packages: A way to group related classes and interfaces, preventing naming conflicts. Corresponds to the directory structure.

Access Protection: Packages add another layer of access control. A member with no explicit access modifier (default access) is visible only to classes within the same package.

Importing Packages: The `import` keyword is used to bring classes from a package into the current namespace, e.g., `import java.util.ArrayList;`.

Interfaces: A reference type in Java. It is a collection of abstract methods. A class `implements` an interface, thereby inheriting the abstract methods of the interface. An interface is a "contract" that a class agrees to follow.

// An interface definition
interface Drivable {
    void drive(); // abstract method (no body)
    void stop();
}

// A class implementing the interface
class Vehicle implements Drivable {
    @Override
    public void drive() {
        System.out.println("Vehicle is driving.");
    }

    @Override
    public void stop() {
        System.out.println("Vehicle has stopped.");
    }
}
Exception Handling

Exception-Handling Fundamentals: An exception is an event that disrupts the normal flow of the program. Exception handling allows you to manage these errors gracefully using `try`, `catch`, and `finally` blocks.

Exception Types: All exceptions are subclasses of the `Throwable` class. `Exception` is for user-recoverable conditions. `Error` is for serious problems that are not expected to be caught (e.g., `OutOfMemoryError`).

Using `try` and `catch`: The `try` block encloses the code that might throw an exception. The `catch` block "catches" the exception and executes code to handle it.

`throw`, `throws`, `finally`:

  • `throw`: Used to manually throw an exception.
  • `throws`: Declares that a method might throw a particular type of exception.
  • `finally`: A block of code that is always executed, whether an exception is thrown or not. Used for cleanup tasks like closing files.

Creating Your Own Exception Subclasses: You can create custom exceptions by extending the `Exception` class. This is useful for handling application-specific errors.

// A method that uses try-catch-finally
public void processFile(String fileName) {
    FileReader reader = null; // Declare outside try
    try {
        reader = new FileReader(fileName);
        // ... code to read from the file ...
        System.out.println("File processed.");
    } catch (FileNotFoundException e) {
        System.err.println("Error: File not found - " + e.getMessage());
    } finally {
        // This block always executes
        System.out.println("Finally block executed.");
        if (reader != null) {
            try {
                reader.close(); // Close the file
            } catch (IOException e) {
                System.err.println("Error closing file.");
            }
        }
    }
}

Enumerations, Type Wrappers, and Other Topics

Enumerations (`enum`): A special data type that enables for a variable to be a set of predefined constants.

Type Wrappers: Classes that "wrap" a primitive type into an object. E.g., `Integer` for `int`, `Double` for `double`. This allows primitives to be used in contexts where objects are required, like collections. The automatic conversion between primitives and their wrapper classes is called autoboxing and unboxing.

I/O Basics

Reading Console Input: Typically done using the `Scanner` class from `java.util`.

Writing Console Output: Using `System.out.println()` or `System.out.print()`.

Reading and Writing Files: Can be done using classes like `FileReader`, `FileWriter`, or more modern approaches with `java.nio.file.Files`.

import java.util.Scanner;

class ConsoleIO {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter your name: ");
        String name = scanner.nextLine();
        System.out.println("Hello, " + name + "!");
        scanner.close();
    }
}
Applet Fundamentals

Important Note: Applets are a legacy, deprecated technology for running Java code in web browsers. They are no longer supported by modern browsers and are not used in new development. Modern web applications use JavaScript frameworks (like React, Angular) for the front-end and Java frameworks (like Spring Boot) for the back-end. This information is provided for historical and syllabus completion purposes.

Other Topics & Modifiers
  • `transient` and `volatile`: `transient` prevents a field from being serialized. `volatile` indicates that a variable's value may be modified by different threads.
  • `instanceof`: An operator that tests if an object is an instance of a specified type (a class, subclass, or interface).
  • `strictfp`: A keyword that restricts floating-point calculations to ensure portability.
  • `native`: A keyword that indicates a method is implemented in another language, typically C or C++.
  • `assert`: A keyword used to test assumptions in your code. Can be enabled or disabled at runtime.
  • `static import`: Allows members (fields and methods) of a class to be used without specifying the class name.
String Handling

The `String` class provides numerous methods for manipulating strings.

  • Constructors/Literals: `String s = "hello";` is most common.
  • `length()`: Returns the number of characters.
  • Character Extraction: `charAt()`, `getChars()`, `getBytes()`.
  • String Comparison: `equals()` (case-sensitive), `equalsIgnoreCase()` (case-insensitive), `compareTo()`.
  • Searching Strings: `indexOf()`, `lastIndexOf()`.
  • Modifying a String: `substring()`, `concat()`, `replace()`, `trim()`. Note: These methods return a *new* string because `String` is immutable.
`StringBuffer` and `StringBuilder`

These classes are used when you need a mutable (modifiable) string. `StringBuilder` is faster but not thread-safe. `StringBuffer` is thread-safe and should be used in multi-threaded environments.

// Example of StringBuilder
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // Modifies the existing object
sb.insert(5, ", Java");
System.out.println(sb.toString()); // Prints "Hello, Java World"