Chapter 2: Basics in Java

In Java, understanding the basic building blocks such as data types is fundamental to developing algorithms. Let's dive into the two main categories of data types in Java: Primitive and Non-Primitive.

1. Data Types

Java is a strongly-typed language, meaning every variable must have a declared data type. There are two main types of data in Java:

1.1 Primitive Data Types

Primitive data types are the simplest and most basic types in Java. They represent single values and do not provide any additional methods or functionality. Java has 8 primitive data types:

  • byte: 8-bit integer (range: -128 to 127)

  • short: 16-bit integer (range: -32,768 to 32,767)

  • int: 32-bit integer (range: ~-2 billion to ~2 billion)

  • long: 64-bit integer (for large numbers)

  • float: 32-bit floating-point number (used for single-precision decimals)

  • double: 64-bit floating-point number (used for double-precision decimals, the default for fractional values)

  • char: 16-bit Unicode character

  • boolean: Represents two values: true or false

Here’s an example program demonstrating primitive data types:

// Java Program to Demonstrate Primitive Data Types
class DataTypes {
    public static void main(String[] args) {
        // Declaring and initializing various primitive types
        char a = 'V';
        int i = 89;
        byte b = 4; // Use byte and short if memory is a constraint
        short s = 56;
        double d = 4.355453532; // By default, decimals are treated as double
        float f = 4.7333434f; // 'f' suffix indicates a float
        long l = 12121L; // 'L' suffix indicates a long value

        // Output the values
        System.out.println("char: " + a);
        System.out.println("int: " + i);
        System.out.println("byte: " + b);
        System.out.println("short: " + s);
        System.out.println("float: " + f);
        System.out.println("double: " + d);
        System.out.println("long: " + l);
    }
}

// Output
char: V
int: 89
byte: 4
short: 56
float: 4.7333436
double: 4.355453532
long: 12121

1.2 Non-Primitive (Reference) Data Types

Non-primitive (reference) data types store references to objects in memory rather than the actual data. These types provide more advanced functionality and flexibility.

  • String: Represents a sequence of characters. Unlike char, which stores a single character, String stores multiple characters.

  • Array: A collection of elements of the same type stored in contiguous memory locations. Arrays can hold both primitive and reference data types.

  • Class: A blueprint from which individual objects are created. Classes define properties (fields) and behaviors (methods) that the objects created from them will have.

  • Object: An instance of a class. Objects are the actual runtime entities used to interact with classes. In the above example, myCar is an object of the Car class.

  • Interface: A contract that specifies a set of abstract methods. Any class that implements the interface must provide implementations for these methods.

// example for String data type
public class StringExample {
    public static void main(String[] args) {
        String greeting = "Hello, Java!";
        System.out.println(greeting);  // Output: Hello, Java!
    }
}

// example for array data type
public class ArrayExample {
    public static void main(String[] args) {
        int[] numbers = {1, 2, 3, 4, 5}; // Array of integers
        System.out.println("First element: " + numbers[0]);  // Output: First element: 1
    }
}

// example for class data type
class Car {
    String model;
    int year;

    // Constructor
    Car(String model, int year) {
        this.model = model;
        this.year = year;
    }

    // Method to display car details
    void displayInfo() {
        System.out.println("Model: " + model + ", Year: " + year);
    }
}

public class Main {
    public static void main(String[] args) {
        Car myCar = new Car("Tesla", 2024);
        myCar.displayInfo(); // Output: Model: Tesla, Year: 2024
    }
}

// example for interface
interface Animal {
    void sound();  // Abstract method
}

class Dog implements Animal {
    public void sound() {
        System.out.println("Barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound();  // Output: Barks
    }
}

2. Control Structures

Control structures allow you to control the flow of execution of your program. Java provides several control structures to help you make decisions and repeat actions.

2.1 If-Else

The if-else statement is used to execute a block of code based on a condition. If the condition is true, the if block is executed; otherwise, the else block (if present) is executed.

// Syntax:
if (condition) {
    // Code to be executed if the condition is true
} else {
    // Code to be executed if the condition is false
}
public class IfElseExample {
    public static void main(String[] args) {
        int number = 10;

        if (number > 0) {
            System.out.println(number + " is positive.");
        } else {
            System.out.println(number + " is not positive.");
        }
    }
}

// output
// 10 is positive.

2.2 Switch

The switch statement allows you to test a variable against a list of values (called "cases") and execute different blocks of code based on the match.

// Syntax:
switch (expression) {
    case value1:
        // Code to be executed if expression equals value1
        break;
    case value2:
        // Code to be executed if expression equals value2
        break;
    // You can have any number of case statements
    default:
        // Code to be executed if no cases match
}
public class SwitchExample {
    public static void main(String[] args) {
        int day = 2;

        switch (day) {
            case 1:
                System.out.println("Sunday");
                break;
            case 2:
                System.out.println("Monday");
                break;
            case 3:
                System.out.println("Tuesday");
                break;
            default:
                System.out.println("Other day");
        }
    }
}
// output
// Monday

2.3 Loops

Loops are used to repeat a block of code as long as a specified condition is met.

2.3.1 For Loop

A for loop is used when the number of iterations is known beforehand.

// syntax 
for (initialization; condition; increment/decrement) {
    // Code to be executed
}

public class ForLoopExample {
    public static void main(String[] args) {
        for (int i = 1; i <= 5; i++) {
            System.out.println("Iteration " + i);
        }
    }
}

// output
// Iteration 1
// Iteration 2
// Iteration 3
// Iteration 4
// Iteration 5

2.3.2 While Loop

A while loop is used when the number of iterations is not known, and you want to repeat the block as long as a condition remains true.

// syntax  
while (condition) {
    // Code to be executed
}

public class WhileLoopExample {
    public static void main(String[] args) {
        int i = 1;

        while (i <= 5) {
            System.out.println("Iteration " + i);
            i++; // Increment i after each iteration
        }
    }
}

// output
// Iteration 1
// Iteration 2
// Iteration 3
// Iteration 4
// Iteration 5

2.3.3 Do-While Loop

A do-while loop is similar to a while loop, but it ensures that the code block is executed at least once, even if the condition is initially false.

// syntax  
do {
    // Code to be executed
} while (condition);

public class DoWhileExample {
    public static void main(String[] args) {
        int i = 1;

        do {
            System.out.println("Iteration " + i);
            i++;
        } while (i <= 5);
    }
}

// output
// Iteration 1
// Iteration 2
// Iteration 3
// Iteration 4
// Iteration 5

3. Comments

Comments are used to explain code and make it more readable. Java supports both single-line and multi-line comments.

  • Single-line comment: Begins with //.

  • Multi-line comment: Enclosed between /* and */.

// This is a single-line comment

/*
 * This is a multi-line comment
 * It can span multiple lines
 */

4. Operators

Java has a wide range of operators to perform operations on variables.

Arithmetic operators: +, -, *, /, % for basic mathematical operations.

Relational operators: ==, !=, >, <, <=, >= for comparing values.

Logical operators: && (AND), || (OR), ! (NOT) for combining boolean conditions.

Assignment operators: =, +=, etc. for assigning and modifying variable values.

Increment and Decrement operators: ++ and -- for increasing or decreasing values.

Bitwise operators: &, |, ^, ~ for working with individual bits.

Shift operators: <<, >> for shifting bits left or right.

public class OperatorsExample {
    public static void main(String[] args) {

        // Arithmetic Operators
        int a = 10, b = 20;
        System.out.println("Addition: " + (a + b));  // 30
        System.out.println("Subtraction: " + (b - a));  // 10
        System.out.println("Multiplication: " + (a * b));  // 200
        System.out.println("Division: " + (b / a));  // 2
        System.out.println("Modulus: " + (b % a));  // 0

        // Relational Operators
        System.out.println("Is a equal to b? " + (a == b));  // false
        System.out.println("Is a not equal to b? " + (a != b));  // true
        System.out.println("Is a greater than b? " + (a > b));  // false
        System.out.println("Is a less than or equal to b? " + (a <= b));  // true

        // Logical Operators
        boolean x = true, y = false;
        System.out.println("Logical AND (x && y): " + (x && y));  // false
        System.out.println("Logical OR (x || y): " + (x || y));  // true
        System.out.println("Logical NOT (!x): " + (!x));  // false

        // Assignment Operator
        int c = 5;
        c += 3;  // Equivalent to c = c + 3
        System.out.println("Assignment c += 3: " + c);  // 8

        // Increment and Decrement Operators
        int d = 10;
        System.out.println("Pre-increment: " + (++d));  // 11
        System.out.println("Post-increment: " + (d++));  // 11 (then d becomes 12)
        System.out.println("Current value of d: " + d);  // 12
        System.out.println("Pre-decrement: " + (--d));  // 11
        System.out.println("Post-decrement: " + (d--));  // 11 (then d becomes 10)
        System.out.println("Current value of d: " + d);  // 10

        // Bitwise Operators
        int e = 5;  // 0101 in binary
        int f = 3;  // 0011 in binary
        System.out.println("Bitwise AND (e & f): " + (e & f));  // 1 (0001)
        System.out.println("Bitwise OR (e | f): " + (e | f));  // 7 (0111)
        System.out.println("Bitwise XOR (e ^ f): " + (e ^ f));  // 6 (0110)
        System.out.println("Bitwise Complement (~e): " + (~e));  // -6 (invert all bits)

        // Shift Operators
        System.out.println("Left Shift (e << 1): " + (e << 1));  // 10 (shifts bits of e left by 1, becomes 1010)
        System.out.println("Right Shift (e >> 1): " + (e >> 1));  // 2 (shifts bits of e right by 1, becomes 0010)
    }
}

5. Exception Handling

Errors and exceptions can occur during program execution. Java provides exception handling to manage these errors gracefully.

  • try-catch Block:

    • try: Contains the code that might throw an exception.

    • catch: Catches specific exceptions and handles them.

    • Example: In the first block, ArithmeticException is thrown when dividing by zero.

  • Multiple catch Blocks:

    • Java allows multiple catch blocks to handle different types of exceptions.

    • Example: In the second block, a NullPointerException is caught, but if the first exception didn't occur, an ArrayIndexOutOfBoundsException might have been caught.

  • finally Block:

    • The finally block is always executed, regardless of whether an exception was thrown or not.

    • Example: In each try-catch-finally example, the finally block prints a message.

  • throws:

    • The throws keyword indicates that a method may throw an exception, and the calling method must handle it.

    • Example: The readFile method declares throws FileNotFoundException. If the file is not found, the exception is propagated to the calling code, which catches it.

  • throw:

    • The throw keyword is used to manually throw an exception.

    • Example: The validateAge method throws an IllegalArgumentException if the age is below 18.

import java.io.*;

public class ExceptionHandlingExample {

    // Method demonstrating throws
    public static void readFile(String fileName) throws FileNotFoundException {
        File file = new File(fileName);
        FileReader fr = new FileReader(file); // This may throw FileNotFoundException
        System.out.println("File is found and opened.");
    }

    public static void main(String[] args) {

        // Example of try-catch-finally
        try {
            // ArithmeticException (Divide by zero)
            int result = 10 / 0;
            System.out.println("Result: " + result); // This line will not execute

        } catch (ArithmeticException e) {
            System.out.println("Caught ArithmeticException: " + e.getMessage());
        } finally {
            System.out.println("Finally block always executes.");
        }

        // Multiple catch blocks
        try {
            String str = null;
            System.out.println(str.length()); // This will throw NullPointerException
            int[] numbers = {1, 2, 3};
            System.out.println(numbers[5]); // This would throw ArrayIndexOutOfBoundsException (won't reach here)

        } catch (NullPointerException e) {
            System.out.println("Caught NullPointerException: " + e.getMessage());
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Caught ArrayIndexOutOfBoundsException: " + e.getMessage());
        }

        // Example of try-catch-finally with I/O and throws
        try {
            readFile("nonexistentfile.txt"); // This will throw FileNotFoundException
        } catch (FileNotFoundException e) {
            System.out.println("Caught FileNotFoundException: " + e.getMessage());
        } finally {
            System.out.println("Finally block after file handling.");
        }

        // Example of throw
        try {
            validateAge(15); // This will throw IllegalArgumentException
        } catch (IllegalArgumentException e) {
            System.out.println("Caught IllegalArgumentException: " + e.getMessage());
        }
    }

    // Method demonstrating throw
    public static void validateAge(int age) {
        if (age < 18) {
            throw new IllegalArgumentException("Age must be 18 or older.");
        } else {
            System.out.println("Age is valid.");
        }
    }
}

Conclusion

In this blog, we covered data types, control flow statements, operators, and exception handling in Java. Without this understanding, no code can be written, let alone algorithms. In future lectures, we will study some examples and gain a deeper understanding of these concepts.

0
Subscribe to my newsletter

Read articles from Vaishnavi Dwivedi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vaishnavi Dwivedi
Vaishnavi Dwivedi